LeetCode31 下一个排列

🔗:https://leetcode.cn/problems/next-permutation/

参考题解:https://leetcode.cn/problems/next-permutation/solution/xia-yi-ge-pai-lie-suan-fa-xiang-jie-si-lu-tui-dao-/

算法思路:

要将获取当前序列的下一个排列,要求此排列满足以下特点:

  • 组合大于当前序列(当前序列最大除外)·
  • 应该是大于当前序列中,最小的那个排列

则需要做到:

  1. 将后面低位的一个大数与前面高位的一个小数进行交换
  2. 有余需要序列紧贴当前序列,所以应该尽可能从低位开始交换
  3. 同时为了使获取的新排列是大于当前排列的最小排列,应该将更换后高位以后的序列进行升序排列
  4. 高位的小数其位置应当尽可能小
  5. 低位的大数其位置也应当尽可能小

下面是大佬的可视化,让人醍醐灌顶。

(https://leetcode.cn/u/imageslr/)

图源@Imageslr

class Solution {
    public void nextPermutation(int[] nums) {
        int N = nums.length;
        int i = N - 2;
        int j = N - 1;
        while(i >= 0) {
            if (nums[i] < nums[j]) {
                //nums[i]是前面最小的较大数
                int k = N - 1;
                // 从后续序列中找到最小的大于nums[i]的数
                // 不可以等于,必须严格大于
                while(k >= i && nums[k] <= nums[i]) {
                    k --;
                }
                // 交换 nums[i] 与 nums[k]
                int tmp = nums[k];
                nums[k] = nums[i];
                nums[i] = tmp;
                break;
            }
            i --;
            j --;
        }
    // 为保证最小,i之后的数字应该升序
        int lo = i + 1;
        int hi = N - 1;
        while(lo < hi) {
            int tmp = nums[hi];
            nums[hi] = nums[lo];
            nums[lo] = tmp;
            lo ++;
            hi --;
        }
    }
}
posted @ 2022-09-13 00:42  Kyara  阅读(16)  评论(0编辑  收藏  举报