链接:
https://leetcode.com/problems/next-permutation/
大意:
给定一个排列(数组表示),按自然顺序找出其下一个排列(也是用数组表示)。如果找不到其下一个排列,则返回整个数组最小的排列(也不是真的返回,只是调整数组中各个元素的顺序)。还是看它给的例子吧:
思路:
第一步:从左往右,找到数组中最后出现的满足前一个大于后一个的数的位置index;
第二步:从index开始,一直到nums.length,找到比nums[index]大且是所有比nums[index]大的数中最小的数的位置minIdx;
第三步:交换nums[index]和num[minIdx],对数组nums在区间[index + 1,nums.length)的数进行排序 最后即可得到比给定序列大的最小序列了
其中,第一步和第二步在代码中可以放在一块执行(即不需要进行两次遍历)
代码:
class Solution {
public void nextPermutation(int[] nums) {
// 如果nums中元素个数为0或1 直接返回
if (nums.length <= 1)
return ;
// 如果nums已经是一个非严格单调递减序列 则对nums按从小到大排序 return ;
int i = 0, index = 0, minIdx = 0; // index为最后一个已知当前元素小于后一元素的当前元素的位置 minIdx为从index到nums.length中,比nums[index]的大的最小的数所在的位置
boolean tag = true; // 用于记录nums是否为一个非严格递减序列
while (i < nums.length - 1) {
if (nums[i] < nums[i + 1]) { // 又找到了一个“递增序列”(相邻两元素)的起点
index = i;
minIdx = i + 1;
tag = false;
} else if (nums[i + 1] < nums[minIdx] && nums[i + 1] > nums[index]) { // 对于之前找到的“递增序列”的起点,找到一个比nums[index]大并且比nums[minIdx]小的元素
minIdx = i + 1;
}
i++;
}
// index == -1则表明在nums中,nums[i] >= nums[i+1] 即为非严格递减
if (tag) {
Arrays.sort(nums);
return ;
}
// 最后只需将nums[index]和nums[minIdx]交换 并且对nums[index+1 ~ nums.length]按从小到大排序即可
int t = nums[index];
nums[index] = nums[minIdx];
nums[minIdx] = t;
Arrays.sort(nums, index + 1, nums.length);
}
}
结果:
结论:
有思路,就能解决。先想思路,再写代码