下一个更大元素III

556. 下一个更大元素 III

给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 

注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 

示例 1

输入:n = 12

输出:21

示例 2

输入:n = 21

输出:-1

思路:

       我们原来做过 下一个排列 那道题很类似。

  从这道题是出题方式来看,我们似乎并不一定要紧挨着的下一个较大值,只需要随便凑出一个更大的数就好。但我们可以直接复用下一个排列的方法——甚至这个方法依然是最合适的办法——因为不管是什么情况,只要有下个更大值(不管几个),我们去拿下一个紧挨着的最大值肯定是最周全的。

  所以还是再复用一下之前的逻辑就好:1.从右往左找“上坡”(上坡即紧挨着的左边小于右边的地方),记录上坡左边界。 2.从右边开始找尽可能小的比上坡左边界大的值。3.两个值做交换后对上坡后面的数值排序。再详细的逻辑解释可以再看这篇

       (当我时隔一段时间再次审视这个思路的时候,对这个“上坡”的作用理解更加清晰了。我们找到了”上坡“就说明找到了交换点,因为有上坡说明必然有一个值比后面的小,从而可以把这个值拿去和后面作交换,让全局变大。而之所以从右向左找这个上坡,就是为了让这个交换的位置尽可能发生在右边也就是位数较小的位置,减少对全局大小的影响,从而得到”紧挨着的“下一个较大值。        最后的排序也很好理解,我们以一个递增的顺序排列可以保证大的数在后面,让数字整体尽可能小。)

代码:

class Solution(object):
    def nextGreaterElement(self, n):
        s = list(str(n))# 将整型处理成字符串列表
        s1 =sorted(s,reverse=True)#将字符串从大到小下排列一下
        if s1==s:
            return -1#如果没有变化,就说明此时已经没有下一个更大元素了
        #现在正式开始找下一个更大元素
        lenth = len(s)#拿到长度
        lelf = lenth-2#left和right从s的最右边开始
        right = lelf+1 
        #ll和rr是用来记录位置的变量
        #ll记录第一个交换值,rr记录第二个交换值
        ll=0   
        rr=0
        while(lelf>=0):#从右往左,找到第一个“上坡”,记录下上坡左边界的值
            if s[lelf]<s[right]:
                ll = lelf
                break
            lelf-=1
            right-=1
        for i in range(lenth-1,ll,-1):#从右到上坡左边界的值,记录下比他大的最小值
            if s[i]>s[ll]:
                rr=i
                break
        #二者交换
        s[ll],s[rr]=s[rr],s[ll]
        s = s[:ll+1]+sorted(s[ll+1:])#ll加1以及以后的数要排序
        s = ''.join(s)
        return int(s) if int(s)<2**31  else -1

  代码中最后要根据题目的案例以及提示进行一个判断和修改,如果最后的结果“越界”了(不是32位整数),就要返回-1。

猜你喜欢

转载自blog.csdn.net/weixin_44492824/article/details/123943512