leetcode -- Next Permutation -- 重点常考

https://leetcode.com/problems/next-permutation/

参考:http://fisherlei.blogspot.hk/2012/12/leetcode-next-permutation.html
http://blog.csdn.net/m6830098/article/details/17291259
http://www.cnblogs.com/zuoyuan/p/3780167.html
算法巧妙。记住那个算法流程图

思路:

总体来说就是从后往前找到第一个递减的数,然后在这个数的右半部分中找到一个比这个数大的最小值,交换这两个值,然后对右半部分排序就可以了.这里的排序其实就是逆置就行。

先看前面2排的话,可以看出来第二排是比第一排要大的,参考字符串比较大小的问题。那么第2个排列是不是第一个排列的下一个排列呢。很明显不是,第3个排列才是, 那么如何获取到下一个排列呢。步骤比较简单:假设数组大小为 n
1.从后往前,找到第一个 A[i-1] < A[i]的。也就是第一个排列中的 6那个位置,可以看到A[i]到A[n-1]这些都是单调递减序列。
2.从 A[n-1]到A[i]中找到一个比A[i-1]大的值(也就是说在A[n-1]到A[i]的值中找到比A[i-1]大的集合中的最小的一个值)
3.交换 这两个值,并且把A[n-1]到A[i]排序,从小到大。A[n-1]到A[i]其实已经是逆序的,只需要将其变成正序即可

class Solution(object):
    def nextPermutation(self, nums):
        """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """
        if len(nums) <= 1: return
        partition = -1
        for i in range(len(nums)-2, -1, -1):
            if nums[i] < nums[i+1]:
                partition = i
                break
        if partition == -1: #如果数字是从后往前一直都递增的话,那么就说明已经是排列数中的最大值了,e.g. 321
            nums.reverse()
            return 
        else:
            for i in range(len(nums)-1, partition, -1):
                if nums[i] > nums[partition]:
                    nums[i],nums[partition] = nums[partition],nums[i]
                    break
        left = partition+1; right = len(nums)-1
        while left < right:#在交换完partition之后,其实这一部分已经是有序的,现在只需要让其正序就行。
            nums[left],nums[right] = nums[right],nums[left]
            left+=1; right-=1

自己重写code

class Solution(object):
    def nextPermutation(self, nums):
        """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """
        partition = -1
        if len(nums) < 2: return
        for i in xrange(len(nums) - 2, -1, -1):
            if nums[i] < nums[i + 1]:
                partition = i
                break # 不要忘记break
        #print partition
        if partition != -1:        
            for i in xrange(len(nums) - 1, -1, -1):
                if nums[i] > nums[partition]:
                    nums[i], nums[partition] = nums[partition], nums[i]
                    break #不要忘记break

        i,j = partition + 1, len(nums) - 1

        while i < j:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
            j -= 1

你可能感兴趣的:(LeetCode)