Leek-- 31. Next arrangement

Topic Link:  31. Next Arrangement - LeetCode

To put it simply, this question means that given an array, an integer is formed in the order of the numbers in the array, let us find the first number that is larger than the current number composed of the numbers in the array, and the number that can be formed There are many numbers larger than the current number, and it is required to find the smallest one. If no larger than the current number can be found, that is, this number is the maximum value of the current number combination, sort the array in ascending order and take the smallest one. . For example [1,2,3] the next greater number than 123 is 132. [3,2,1] is already the maximum value among the integers that these three numbers can form, if no larger combination can be found, then sort [3,2,1] in ascending order to get [1,2,3 ] is the answer.

Problem-solving ideas:

The reference code is as follows, and a detailed explanation has been attached. I believe that all smart friends can understand and learn this question.

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        //利用i和j下标从后往前查找能组成比所给nums组合更大的数
        int i = nums.size() - 2;
        int j = nums.size() - 1;

        //由于i是前一个元素的下标,j是后一个元素的下标,所以i是大于等于0的
        //j是大于0的
        while (i >= 0 && j > 0)
        {
            //由于我们是从后往前找的,所以如果前一个元素大于等于后一个元素,
            //说明从nums[i]开始往后的元素都是升序的,即最大的,所以i--,j--
            // 继续往前找,直到找到nums[i]<nums[j]的时候,则从nums[i]开始
            //往后的数字组合才能找到比当前组合更大的
            if (nums[i] >= nums[j])
            {
                i--;
                j--;
            }
            else
            {
                break;
            }
        }

        //如果i<0,说明给定的这个组合就是这个数组元素所能组成的最大值,
        //找不到比这个数更大的组合了,将数组排成升序,返回最小值
        if (i < 0)
        {
            sort(nums.begin(), nums.end());
            return;
        }

        //找到的nums[i]<nums[j],先用tmp保存下来
        int tmp = nums[i];

        //mini用来记录比nums[i]大的最小的数字的下标,可以初始化为j,因为
        //nums[j]就是其中一个比nums[i]的数,不影响后面的更新,不能给mini
        //随意赋值
        int mini = j;

        //min用来记录nums[i]往后的数与nums[i]的最小差距
        int min = nums[i+1] - nums[i];

        //由于j位置的数据已经被上面记录过了,所以我们可以从j+1的位置开始往后找出
        //与nums[i]最接近的并且最小的数,即与tmp最接近的并且最小的数
        for (int m = j + 1 ; m < nums.size(); m++)
        {
            //如果往后找到比tmp大并且与tmp差距值更小的数,就记录更新mini
            if (nums[m] > tmp && nums[m] - tmp < min)
            {
                mini = m;
            }
        }

        //mini就是从i开始往后找到的比nums[i]大并且最小的数的下标,使nums[i]和
        //nums[mini]交换,具体实例可以结合上面例题的图片解释
        swap(nums[i], nums[mini]);

        //最后把nums[i]后面的数进行升序排序即可
        sort(nums.begin() + i +1, nums.end());


    }
};

The above is the detailed answer process of this question, have you learned it? If it is helpful to you, then be careful and pay attention to it. We will continue to update the classic topics on Likou in the future. See you in the next issue! ! ! ! !

Guess you like

Origin blog.csdn.net/weixin_70056514/article/details/131038435