codeTop100题(41)31. 下一个排列

75 阅读1分钟

1. 题目

31. 下一个排列

2. 分析

下一个排列,其实是我们要尽可能要让数字比原来大,但是又要数据经历增长比较小。例如

  • 我们就需要从右往左找到一个相邻升序的数,即132中的1和3(132的下一个排列是213);或者123中的2和3(因为123的下一个排列是132)
  • 然后1和2进行交换,即右边第一个比1大的数字
  • 交互1 和 2
  • 变成了231,还得对31进行排序

注:如果找不到升序的,直接排序吧

3. 代码

public static void nextPermutation(int[] nums) {
    if (nums.length == 1) {
        return;
    }
    //从右边往前找一个能变大的数
    int l = nums.length - 1, r = nums.length - 1;
    //找个升序的
    for (; l > 0; l--) {
        if (nums[l] > nums[l - 1]) {
            break;
        }
    }
    l--;
    if (l >= 0) {
        //找到比l大的r
        for (; r > l; r--) {
            if (nums[r] > nums[l]) {
                break;
            }
        }
        //进行交换
        if (l < r) {
            swap(nums, l, r);
        }
    }
    l += 1;
    r = nums.length - 1;
    //把i - 最后的数组进行一下排序
    //选择排序
    for (int i = r; i > l; i--) {
        int max = i;
        for (int j = l; j < i; j++) {
            if (nums[j] > nums[max]) {
                max = j;
            }
        }
        swap(nums, i, max);
    }
}

public static void swap(int[] nums, int a, int b) {
    int t = nums[a];
    nums[a] = nums[b];
    nums[b] = t;
}