LeetCode31.下一个序列
实现获取“下一个排列”的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100
思路:首先从尾到头找到第一个下降的位置k,即该位置满足nums[k]>nums[k-1],所有k之后的元素都是降序的(从头到尾),这个排列是最大的,无法更大。若要使序列增大,只能将nums[k-1]和nums[k~u-1]交换。如何获取u:从k出发,找到第一个小于nums[k-1]的位置u,那么nums[u-1]就是第nums[k-1]大的最小的数字(k到nums.size()-1这个区间中)。交换nums[k-1]和nums[u-1],然后对k之后的数组升序排序即可(原本是降序的,只要颠倒数组即可)。
Java代码如下:
class Solution {
public void nextPermutation(int[] nums) {
int k = nums.length - 1;
while(k > 0 && nums[k-1] >= nums[k]) { // 找到第一个下降的位置(从尾到头)
k--;
}
if(k <= 0) { // 此时整个数组都是降序的,反转数组即可
int l = 0, r = nums.length - 1;
while(l < r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;
}
} else {
int u = k;
while(u < nums.length && nums[u] > nums[k-1]) { // 找到第一个比nums[k-1]大的位置
u++;
}
int temp = nums[k-1];
nums[k-1] = nums[u-1];
nums[u-1] = temp;
int l = k,r = nums.length - 1;
while(l < r) {
temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;
}
}
}
}