leetcode31.下一个排列

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

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

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

完整代码

这道题大概知道如何求结果,自己手算可以算的出来,但是不知道代码实现是什么思想,参考讨论区的思想如下。

基本思想:

  1. 从右往左遍历数组,找到第一个正序的数,下标为 i(后一个大于前一个的数),例如:[3,4,5,2,1],找到5
  2. 将该数一直到结尾的数逆序,[3,4,1,2,5]
  3. 将第 i-1 个数和 i 后面的比第 i-1 个数大的最小的数 交换 [3,5,1,2,4]
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if(nums.size()<2)
            return;
        int len=nums.size();
        
        //1.从右往左找到第一个后一个比前一个大的数
        int i=len-1;
        while(i>0&&nums[i]<=nums[i-1])
            --i;
        
        //2.将第i个数一直到结尾的数逆序
        reverse(nums.begin()+i,nums.end());
        
        //3.交换第i-1个数和i之后中比第i-1个数大的数中的最小数,不一定是结尾位置的数,因为其后的数都是递增排序的,所以从前往后遍历,第一个找到的就是
        if(i>0){//如果i==0就不用交换了
            for(int k=i;k<len;++k){
                if(nums[k]>nums[i-1]){
                    int temp=nums[k];
                    nums[k]=nums[i-1];
                    nums[i-1]=temp;
                    break;
                }
            }
        }        
    }
};
执行结果:通过
显示详情
执行用时 :12 ms, 在所有 C++ 提交中击败了60.65%的用户
内存消耗 :8.4 MB, 在所有 C++ 提交中击败了95.94%的用户

做完这道题,我觉得看到一个问题,只要是有了清晰的思路,只需将思路用代码体现出来就OK。

发布了217 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_31672701/article/details/103826313