Leetcode每日一题:31.next-permutation(下一个全排列)

在这里插入图片描述
题目意思是找到给出数字序列的下一个更大排列,比如给定1,2,3那么就是找到比123大的数中最小的数,即132,那么它的排列就是1,3,2

思路:如果全都是降序的,那么肯定不存在比它大的排列,所以
step1:一定是找到里面的一个升序对,然后把大数与小数交换位置,比如12843,交换2,8得到18243,但如果交换1,2,就会得到比18243更大的21843,所以要从右向左找到第一对升序对
step2:18243并不是大于12843的最小的数,原因是这个8太大了,很明显13842大于12843但比18243小,所以我们要在2的右边找到大于2的最小的数,把它与2交换即可,这里因为28是第一对升序对,所以2的后面一定都是降序的,所以只需从右向左找到大于2的最小的数,再交换,这里得到13842;
step3:经过以上两步,我们找到了13842,但它仍不是最小的,因为13248比12843大但比13842小,所以这里确定了13,我们就要把3后面的所有数改为升序排列,这样一定是最小的,因为 3后面是降序的,所以我们只需把它们翻转下即可;
下一个排列算法详解:思路+推导+步骤,看不懂算我输!
在这里插入图片描述
在这里插入图片描述

void nextPermutation(vector<int> &nums)
{
    
    
    int len = nums.size();
    if (len < 2)
    {
    
    
        return;
    }
    int i = len - 2, j = len - 1, k = len - 1;
    //step1:从后向前找到第一对升序对
    while (i >= 0 && nums[i] >= nums[j])
    {
    
    
        i--;
        j--;
    }
    if (i < 0) //如果整个数组都是降序,那么设j=0,后面逆置nums[j~end]
    {
    
    
        j = 0;
    }
    else //找到升序对
    {
    
    
        //step2:从后向前找到第一个大于nums[i]的最小的数(肯定能找到)
        while (k > i && nums[i] >= nums[k])
        {
    
    
            k--;
        }
        //交换nums[i]和nums[j]
        int temp = nums[i];
        nums[i] = nums[k];
        nums[k] = temp;
    }

    //step3:逆置nums[j~end]
    while (j < len - 1)
    {
    
    
        int temp = nums[j];
        nums[j] = nums[len - 1];
        nums[len - 1] = temp;
        j++;
        len--;
    }
}

猜你喜欢

转载自blog.csdn.net/wyll19980812/article/details/109235586