LeetCode 31. Next Permutation (下一个排列)

原题

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

`1,2,3` → `1,3,2`
`3,2,1` → `1,2,3`
`1,1,5` → `1,5,1`

Reference Answer

思路分析

首先需要知道什么是全排列,参考Wikipedia

字典序法
字典序,就是将元素按照字典的顺序(a-z, 1-9)进行排列。以字典的顺序作为比较的依据,可以比较出两个串的大小。比如 “1” < “13”<“14”<“153”, 就是按每个数字位逐个比较的结果。对于一个串“123456789”, 可以知道最小的串是“123456789”,而最大的串“987654321”。这样针对这个串以字典序法生成全排列生成全排列,就是依次生成“123456789”->“123456798”->…->“987654312”->"987654321"这样的串。字典序法要求这一个与下一个有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。[2]

很有技巧的题目。

先找到从后向前数,第一个降序的位置,把此位置后面的翻转。再把这个降序数字和后面第一个比它大的位置交换即可。

如果从第n个数字到最后都是递减的并且第n-1个数字小于第n个,说明从第n个数字开始的这段序列是字典序组合的最后一个,在下一个组合中他们要倒序变为字典序第一个,然后从这段序列中找出第一个大于第n-1个数字的数和第n-1个数字交换就可以了。

举个栗子,当前组合为12431,可以看出431是递减的,同时4>2,这样我们把431倒序,组合就变为12134,然后从134中找出第一个大于2的数字和2交换,这样就得到了下一个组合13124。对于完全递减的组合例如4321在倒序之后就可以结束了。

大体和Leetcode的这个解答方式类似:

在这里插入图片描述

Code

class Solution:
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        pre_index = len(nums) - 2
        after_index = len(nums) - 1
        while pre_index >= 0 and nums[pre_index] >= nums[pre_index+1]:
            pre_index -= 1
        if pre_index >= 0:
            while nums[after_index] <= nums[pre_index]:
                after_index -= 1    
            nums[pre_index], nums[after_index] = nums[after_index], nums[pre_index]
        nums[pre_index+1:] = sorted(nums[pre_index+1:])
        

Note

  • 规律不是很好找,这道题还是建立在本身就知道这种排列结构比较容易做;
  • 注意内层循环中while nums[after_index] <= nums[pre_index]:,必须是小于等于,不然不能得到正确结果,做题时候在这浪费了不少时间。

参考文献

[1] https://blog.csdn.net/fuxuemingzhu/article/details/82113409
[2] http://www.cnblogs.com/grandyang/p/4428207.html

猜你喜欢

转载自blog.csdn.net/Dby_freedom/article/details/85226270