思路;
求下一个排列可以看做给一个数字,将位数重新排列,求出下一个更大的数字。
找下一个更大的数字需要做到:
1 从右向左找到第一个相邻的递增的两个数
2 将较小的那个数和较大的那个数右边从右向左第一个大于较小数的数交换。
3 把较大数及其右边从递减转为递增。
4 如果第1步没有找到,说明已经是最大的数字了,直接转为递减。
总结:
想让下一个数变大,就要将右边的大数和左边的小数交换。
但变大后要尽可能小,发生交换的位置要尽可能在右边,从右向左找。
所以先从右向左找到第一个相邻的递增的两个数。
然后再从右向左找到第一个比递增两个数中小的那个大的数,然后交换。
最后把降序的部分转为升序,因为升序是最小的,降序是最大的。
代码:
class Solution {
public void nextPermutation(int[] nums) {
int n = nums.length;
if(n <= 1) return;
int i = n - 2, j = n - 1, k = n - 1;
// 1 从右向左找到第一个相邻的递增的两个数
while(i >= 0 && nums[i] >= nums[j]) {
i--;
j--;
}
// 2 将较小的那个数和较大的那个数右边从右向左第一个大于较小数的数交换。
if(i >= 0) {
while(nums[i] >= nums[k]) {
k--;
}
int t = nums[i];
nums[i] = nums[k];
nums[k] = t;
}
// 3 把较大数及其右边从递减转为递增。
int l = j, r = n - 1;
while(l < r) {
int t = nums[l];
nums[l] = nums[r];
nums[r] = t;
l++;
r--;
}
}
}
参考: