leetcode 31. 下一个排列

文章讲述了作者在解决nextPermutation编程题时的经历,从初次遇到困难,参考他人思路,到四个月后重新理解并掌握该问题的关键在于找到升序对组并进行特定交换和排序。代码实现涉及数组操作,包括寻找升序对、交换元素和部分数组排序。
摘要由CSDN通过智能技术生成

2023.5.20

题目描述:

         理解题目意思都花了10几分钟.... 半天没有想到什么好解的办法,直接移步评论区,扫了几眼别人的思路,回来自己敲代码,第一遍通过50多例,优化了一下代码,第二遍通过200多例,但还是出错。 总是有些情况没考虑到,真的崩溃...

        最后没辙了,去看了下别人的代码,虽然代码看懂了,但我感觉我一辈子自己都想不出来这样的代码... 下面附上自己手敲的代码,希望几个月后回来这道题我能自己想出来。

class Solution 
{
public:
    void nextPermutation(vector<int>& nums) 
    {
        int n = nums.size();
        int i = n-1;
        int j = i-1;
        int k = n-1;
        
        while(j >= 0 && nums[i] <= nums[j])
        {
            j--;
            i--;
        }
        if(j >= 0)
        {
            while(nums[k] <= nums[j])
            {
                k--;
            }
            swap(nums[j] , nums[k]);
        }
        sort(nums.begin()+j+1 , nums.end());
    }
};


         感觉这道题没有什么技巧性,就是思路很新奇,很难想,只要求自己笔试遇到一样的题能做出来就行。


2023.9.25

        时隔四个月,二刷。 本题思路有两个关键点:①下一个排列需要比当前排列大②下一个排列和当前排列的差值需要尽可能小。   直观思路是从数组后面选一个大数和前面的小数交换,这样可以满足第一个条件,但是第二个条件则需要加一些限制。 具体步骤如下:

        从后往前遍历,找到第一个升序的对组,如数组[1,2,3,8,5,7,6,4],从后往前找第一个升序对组是[5,7],将5的索引记录下来,放入变量start中。此时7往后的数字肯定都是降序的,再从后往前找到第一个大于5的数字,这个数是大于5的数字中最小的那一个,即6,将该数的索引放入变量index中。 将两个数交换,得到[1,2,3,8,6,7,5,4],再将start往后的数组排序。 这样做就可以保证下一个排列是大于当前排列、且幅度最小的排列了。

        代码如下:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int start=0;
        //从右往左 找到第一对 升序对组 靠左的那个数start。
        for(int i=nums.size()-2; i>=0; i--)
        {
            if(nums[i] < nums[i+1])
            {
                start = i;
                break;
            }
        }
        int index = 0; 
        //从右往左 找到大于start的数中 最小的那一个
        for(int i=nums.size()-1; i>start; i--)
        {
            if(nums[i] > nums[start]) 
            {
                index = i;
                break;
            }
        }
        //数组是降序的情况:直接反转
        if(start == index) 
        {
            reverse(nums.begin(),nums.end());
            return;
        }
        swap(nums[start],nums[index]);
        sort(nums.begin()+start+1,nums.end());
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值