【LeetCode】31. Next Permutation 下一个排列

一、概述

傻逼题目。我看题目根本无法理解它的意思。什么叫“the lexicographically next greater permutation of numbers”。

直译过来是“按字典序的下一个更大的数字的排列”。十分模糊的概念。

后来试了无数次,见下图

才弄明白,这个下一个序列指的是:对于最后一个“先升后降的部分”,设峰顶前一个元素为a,在下降部分找到最小的大于a的元素b,swap一下a和b,然后重排b之后的元素。

我就想知道,我用这么长的句子总结出的概念,是如何表达成上面那个名词的。郁闷死。

后来发现可以这样表述:

输入一个序列,将其看做一个十进制整数,对于所有数字能够组成的所有数,找到最小的大于它的数。

lzzscl,还是难理解。

二、分析

1、我的算法

时空复杂度还可以,我就只讲我自己的了。这题目考的是语文,不是算法。见下图:

这是我一个一个修改输入才得到的输出序列,从上往下,上一个是下一个的输入,下一个是上一个的输出。

我们可以看到:

1234为升序,于是3与4调换;

1243先升后降,于是2与3调换;

1324升降升,于是2与4调换;

1342先升后降,于是3与4调换;

......

调换之后都有将后面的序列按从小到大重排序。

可以发现,a与b调换,a的位置是不变的,b的位置经常在变化。

a的位置是哪个呢?观察可知,a的位置可以按如下描述:

对于最后一个从na到nb的升序列,a的位置为nb-1。

b的位置也有讲究,对于最后的nc到nd的降序列,有时候b是最后一个,有时候是第一个。但是由于后面的序列元素不够,因此还需要更多的例子。

对于序列146532,其结果为152346,4与5调换。这次既不是第一个,又不是最后一个。

观察该序列可知。对于降序列6532,5是最小的大于4的元素。所以b的位置就这样确定了。

a和b的位置都确定之后,交换位置并重排序即可。代码如下:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int len=nums.size();
        if(len==1)
            return;
        int now=len-1;
        int s=0;
        int start=-1;
        while(s<len-1)
        {
            if(nums[s]<nums[s+1])
                start=s;
            s++;
        }
        if(start==-1)
        {
            sort(nums.begin(),nums.end());
            return;
        }
        int end=start+1;
        for(int i=start+2;i<len;i++)
        {
            if(nums[i]>nums[start])
            {
                end=i;
            }
            else
            {
                break;
            }
        }
        swap(nums[start],nums[end]);
        sort(nums.begin()+start+1,nums.end());
        return;
    }
};

start用于找a,end用于找b。

别的没什么了。

三、总结

这题简直就是一个黑箱,题目解释屁用没有,我完全是靠自己调输入输出才得到的结果。

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值