Leetcode刷题记录——31. 下一个排列

在这里插入图片描述

此题比较难考虑
我们这样想:

先考虑最难搞的情况 也就是题目中所说的“不存在更大的排列”
此时,输入是全递减序列
这时,我们只需要把原数组倒序即可

接下来我们考虑一般的情况,也就是存在更大的排列
此时,我们只需要把比输入序列组成的N位数中大于原顺序的N位数最小的数即可
如 比1 3 2 更大的 数里 最小的 是 2 1 3

为了实现这个功能
我们观察序列的末尾部分,如果末尾是升序
例如 2 1 3 4
我们只需要把最后两个交换即可

如果末尾是降序,因为我们在一开始已经排除了全降序的可能
因此,序列在最后的部分 一定是 先递增 再递减
如2 1 4 3
我们观察序列的后半部分,即递减前一个数字,即上面的 1 4 3
此时,我们称4为峰顶a,称1为b,我们需要找到峰顶及后面(含峰顶)比b大的最小的数c
然后将b和c两个位置的数字交换,最后再将b之后的序列倒序
即可

class Solution:
    def nextPermutation(self, nums):
        """
        Do not return anything, modify nums in-place instead.
        """
        length = len(nums)
        done = False

        for i in range(1,length):
            if nums[i-1] < nums[i]:#后一个小于前一个
                break
            elif nums[i] <= nums[i-1] and i == length - 1:
                nums[:] = nums[::-1]
                done = True#全部是递减,此时是最后一个全排列,直接改为第一个即可
        if done == False and length > 1:
            if nums[-1] > nums[-2]:#若尾部是升序,我们将尾部的倒数两个交换即可
                nums[length - 1],nums[length - 2] = nums[length - 2],nums[length - 1]
                #nums[-1],nums[-2] = nums[-2],nums[-1]
            else:
                #先找到尾部降序的起点a,然后找到这个起点之前的那个低谷点b
                #然后找尾部降序中最小的比b大的数字c
                index = length - 1
                while nums[index] <= nums[index - 1]:
                    index -= 1
                #此时nums[index] > nums[index - 1]
                b = nums[index - 1]
                a = nums[index]#峰顶
                #先看看最后一个是不是c
                if nums[-1] > b:
                    nums[-1],nums[index - 1] = nums[index - 1],nums[-1]
                else:
                    for i in range(index,length - 1):
                        if nums[i] > b and nums[i+1] <= b:

                            nums[i],nums[index - 1] = nums[index - 1],nums[i]

                nums[index:] = nums[index:][::-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值