LeetCode31 下一个排列
🔗:https://leetcode.cn/problems/next-permutation/
算法思路:
要将获取当前序列的下一个排列,要求此排列满足以下特点:
- 组合大于当前序列(当前序列最大除外)·
- 应该是大于当前序列中,最小的那个排列
则需要做到:
- 将后面低位的一个大数与前面高位的一个小数进行交换
- 有余需要序列紧贴当前序列,所以应该尽可能从低位开始交换
- 同时为了使获取的新排列是大于当前排列的最小排列,应该将更换后高位以后的序列进行升序排列
- 高位的小数其位置应当尽可能小
- 低位的大数其位置也应当尽可能小
下面是大佬的可视化,让人醍醐灌顶。
图源@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 --;
}
}
}