【Leetcode 31】下一个排列

题目描述

在这里插入图片描述

解题思路

理解题意

本题首先最大的难点是理解题目的意思,题目意思是给定一个有几个数字组成的数值,将这些数字重新排列,刚好得到比该数值大的新数值,如果没有比题目给定的数值大的就返回题目给的数值。比如说:给定的数值为123,比123大的数值有132、213、231、312、321,但题目要求的是刚好比123大一位的数值,就是132,而不是所有的更大数值,还要求空间复杂度为O(1)。
那么如何找到这个数呢,我们开始寻找规律比如找出比上述的123刚好大一位的数值,为132,那么就是2和3交换位置。思考一下,难道所有的数交换位置就结束了吗?这是不一定的,因为交换后的数字变大了,但不是刚好大于原来的数值的。
再举一个例子,比如要求找到刚好比158476531大的数,那么从十位数3开始,看十位数的右边有没有大于3,没有就再看百位数5右边是否有大于5的,依次类推,可以看到3,5,6,7的右边都没有大于他们本身的数。那么就来到4,4的右边有很多大于4的,选择刚好大于4的5进行交换得到158576431,这个数大于158476531,但不是刚好大于,则不符合要求,这是还需要将5右边的数按从小到大排列,得到158513467,符合要求结束。

解题思路

将给定的数字组成的序列,从右到左找到第一个不再递增的位置,将该位置的数字与右边刚好大于它的数字交换,再将该位置右边的数字降序排列,得到最终结果

python代码

class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        i = len(nums)-2
        # 找到第一个不再递增的位置
        while i >= 0 and nums[i+1]<=nums[i]:
            i -= 1
        # 如果到了最左边,就直接倒置输出
        if i >= 0:
            # 刚好找到大于num[i]的位置
            j = len(nums)-1
            while j >= 0 and nums[j]<=nums[i]:
                j -= 1
            # 交换
            self.swap(nums, i, j)
        # 利用倒置进行排序
        self.reverse_ll(nums, i + 1)

    def swap(self,nums, i, j):
        temp = nums[j]
        nums[j] = nums[i]
        nums[i] = temp
    
    def reverse_ll(self,nums,start):
        i = start
        j = len(nums) - 1
        while i < j:
            self.swap(nums, i, j)
            i += 1
            j -= 1

s = Solution()
res = s.nextPermutation([1,2,3])
print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值