实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:最初错误的想法,从左到右维护一个单调递增的序列,这样就可以知道每个数左边第一个小于它本身的下标;然后,从右向前扫,如果它左边存在小于它的元素,交换位置(比如 i - n 与 i 交换),并将 i - n 后边的元素排序。
一交,wa了
样例 : 5 2 0 2 3 1 0
输出 : 5 2 1 0 0 2 3
正确 : 5 2 0 3 0 1 2
我知道是临界值的位置找错了,于是多次模拟了几组样例,想到了:假设某个值为临界交换值 i,那么它右边必然有一个大于它的值 j,并且 j 值越小越好,思路呼之欲出。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int len = nums.size();
if(len < 2) return ;
bool flag = false;
for(int i=len-1;i>=0;i--){
int x = 0X3f3f3f3f,index = -1;
for(int j=len-1;j>i;j--){
if(nums[j] > nums[i]){
if(x > nums[j]){
x = nums[j];
index = j;
}
flag = true;
}
}
if(flag){
swap(nums[i], nums[index]);
sort(nums.begin()+i+1,nums.end());
break;
}
}
if(!flag) sort(nums.begin(),nums.end());
}
};