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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值