leetcode 每日一题 31. 下一个排列

扫描法

思路:

题目的意思是给定一个数组,按数组给的顺序拼接其中每个数字得到一个数字num,我们要做的是调换下数组中一些元素的位置,使新的数组按顺序排列后的数字num2,刚好是下一个比num大的数字。

例如:给定数组 [2,4,3,1],拼接后的数字是2431,用这四个数字能得到刚好比2431大的下一个排列是3124,所以调换后的数组应该是[3,1,2,4]

那么现在要研究如何确定要调换的位置,我们可以发现找到比一个排列大的下一个排列,可以从这个排列的尾部开始扫描,当发现有破坏降序的数字出现时记录一下,接着在尾部找到比这个数字大的数字,二者对调,对调后把这个数字之后的排列翻转,即可得到相应结果。

例如:

[4,3,5,6,2,1,0]

①先找到位置i

 

②再找到位置j

 

③交换i,j

 

④翻转i之后的元素

 

得到结果[4,3,6,0,1,2,5]

代码:

class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        def swap(nums,i,j):
            temp = nums[i]
            nums[i] = nums[j]
            nums[j] = temp
        def reverse(nums,start):
            i,j = start,len(nums)-1
            while i<j:
                swap(nums,i,j)
                i += 1
                j -= 1
        h = len(nums)-2
        while h>=0 and nums[h+1]<=nums[h]:
            h -= 1
        if h >= 0:
            k = len(nums) - 1
            while k>=0 and nums[k]<=nums[h]:
                k -= 1
            swap(nums,h,k)
        reverse(nums,h+1) 

 

 

posted @ 2020-05-13 12:50  nil_f  阅读(123)  评论(0编辑  收藏  举报