LC31-下一个排列-next-permutation

2021/11/15 基础全排列

# 题意

实现 next-permutation 函数。

如果不存在下一个更大的排列,则返回最小的排列(即升序排列)。

要求 O(1) 空间。

# 思路

思路来自 powcai提供的题解 (opens new window)

算法在 维基百科 (opens new window) 上有明确的描述:

  1. 先找出最大的索引 k 满足 nums[k] < nums[k+1],如果不存在,就翻转整个数组;
  2. 再找出另一个最大索引 l 满足 nums[l] > nums[k];
  3. 交换 nums[l] 和 nums[k];
  4. 最后翻转 nums[k+1:]。

# 代码

class Solution {
    public void nextPermutation(int[] nums) {
        int size = nums.length - 1;
        // 1. 先找出最大的索引 k 满足 nums[k] < nums[k+1],如果不存在,就翻转整个数组;
        int k = size - 1;
        while (k >= 0 && nums[k] >= nums[k + 1]) {
            k--;
        }
        if (k == -1) {
            reverse(nums, 0);
            return;
        }
        // 2. 再找出另一个最大索引 l 满足 nums[l] > nums[k];
        int l = size;
        while (l >= 0 && nums[l] <= nums[k]) {
            l--;
        }
        // 3. 交换 nums[l] 和 nums[k];
        swap(nums, l, k);
        // 4. 最后翻转 nums[k+1:]。
        reverse(nums, k + 1);
    }

    private static void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }

    private static void reverse(int[] nums, int l) {
        int r = nums.length - 1;
        while (l <= r) {
            swap(nums, l, r);
            l++;
            r--;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Last Updated: 2021/12/7 下午2:23:53