下一个全排列

57 篇文章 0 订阅

leetcode中的原题是:

实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列。

如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列)。

修改必须是原地的,不开辟额外的内存空间。

这是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

这个问题其实解释的很清楚了,但是不知道当时怎么了,我以为非常复杂。

假如传入的是数组,为nums。

我想象中的的解法是,从给定数组的后面往前面找,找到给定数组中的一个索引,要求是这个索引(index)对应的值大于索引(index+1)对应的值,然后让这两个索引对应的值互相交换就OK了。(假如index之后的元素为abcde,那么abcde是从大到小>排列的,即a>b>c>d>e)

为什么这么找呢?

是因为,交换上述索引的值可以使的整体增大的值最小。

你看啊,假如nums=[1,4,5,2,3],交换2和3的位置边得的排列(变成14532),是小于4和5交换得到的排列的(变成15423)。这个很简单吧?(一个是千位数的增加,一个是十位数的增加)

但是这样得到就是想要的结果吗?

假如nums=[1,3,6,5,4,2],交换3和6的值就是下一个排列吗?

不是的,由13开头变为16开头,要知道中间还有15或者14开头的,那么到了这一步你是否想到交换哪两个值的位置了?

当然是3和4的位置。

这就解决了到底应该和谁交换的问题。和谁交换呢?找到了索引index和index+1之后就应该交换索引大于index的最小的大于index索引对应的值,就是3后面最小的大于3的值4,那么就应该交换3和4的位置。

那么交换完了位置就可以了吗?

这个是不行的,因为交换完了之后,就变成146532,在此之前还有142356是不是?

交换完之后index之后的值,是从大往小排列的。那么14开头最小的排列就是咱们要找的排列。所以应该完成对index之后的值进行逆序排列。然后就解决了这个问题。


class Solution:
    def nextPermutation(self, nums):
        if len(nums)<2:
            return
        ind=len(nums)-1
        while nums[ind-1]>=nums[ind] and ind>0:
            ind-=1
        if ind==0:
            self.traverse(nums,0,len(nums)-1)
            return
        else:
            for i in range(len(nums)-1,ind-1,-1):
                if nums[i]>nums[ind-1]:
                    nums[i],nums[ind-1]=nums[ind-1],nums[i]
                    self.traverse(nums,ind,len(nums)-1)
                    return        
    def traverse(self,nums,start,end):
        while start<end:
            nums[start],nums[end]=nums[end],nums[start]
            start+=1
            end-=1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值