leetcode 力扣 31 下一个排列

59 阅读1分钟

我们可以这样来看,不要把它当成字典序,把它当成一个数,比如123456,我们把它分开两半,123456,离四百五十六最近最大的数就是465

所以关键是怎么找到最近最大的数

最近,就是从后往前找,找到第一组递增的两个相邻的数,其中第二个数是它往后到结尾最大的数,它后面的数必定是不增或递减的。

  • 比如5243里的244是它往后最大的数,24是递增的,43是递减的

  • 再从后往前找到第一个比2大的数,也就是3,是它往后第二大的数。交换23,得到5342。也就是将该范围内第二大的数,放在最大的数前

  • 再将3后面的数反转,结果必然是不减或递增的,目的是使其最小化,以获得“最近”的效果,得到5324

下面是另一个例子 image.png

image.png

image.png

image.png

class Solution {
    public void nextPermutation(int[] nums) {
        int n = nums.length;
        if(n == 1){
            return;
        }

        int i = n - 2;
        int j = n - 1;
        while(i >= 0 && nums[i] >= nums[j]){
            i--;
            j--;
        }

        int k = n - 1;
        if(i >= 0){
            while(nums[k] <= nums[i]){
                k--;
            }

            swap(nums, i, k);
        }

        for(i = j, j = n - 1; i < j; i++, j--){
            swap(nums, i, j);
        }
    }

    public void swap(int[] nums, int idx1, int idx2) {
        int temp = nums[idx1];
        nums[idx1] = nums[idx2];
        nums[idx2] = temp;
    }
}