Leetcode one question of the day: 31.next-permutation (next-permutation)

Insert picture description here
The question means to find the next larger permutation of the given number sequence. For example, if given 1,2,3, find the smallest number among the numbers greater than 123, namely 132, then its permutation is 1,3,2;

Idea: If all are in descending order, then there must be no higher order, so
step1: Must find an ascending pair inside, and then swap the position of the large number and the decimal number, for example, 12843, exchange 2, 8 to get 18243, but if you exchange 1, 2, you will get 21,843, which is larger than 18243, so you have to start from the right Find the first pair in ascending order to the left ;
step2: The smallest number greater than 12843 of 18243 is not, because this 8 too, obviously 13842 is greater than 12843 but less than 18243, so we need a minimum number greater than 2 to find the right 2, put it with 2 exchange that is But, because 28 is the first pair in ascending order, the following 2 must be in descending order, so you only need to find the smallest number greater than 2 from right to left, and then exchange, here you get 13842;
step3: After the above two steps, we found the 13842, but it still is minimal, because more than 12843 13248 13842 small than big but, so here identified 13, we will put all behind number 3 was changed to ascending order so certain, It is the smallest, because 3 is in descending order, so we only need to flip them down; the
next arrangement algorithm is explained in detail: idea + derivation + steps, if you don't understand it, I lose!
Insert picture description here
Insert picture description here

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--;
    }
}

Guess you like

Origin blog.csdn.net/wyll19980812/article/details/109235586