【LeetCode练习题】Next Permutation

时间:2023-03-09 16:47:45
【LeetCode练习题】Next Permutation

Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

题目意思:

给定一组数字,求他的下一个排列。如果已经是最大的排列了,那么就把他调整成最小的排列。而且必须是在num数组中原地调整,不能增加额外的内存分配。

解题思路:

又是一道全排列的题目,我突然就想到了之前的那个求Permutation的题,于是乎第一反应就是不管三七二十一先把你所有的排列都求出来然后存起来,跟给定的排列比较,然后按顺序的下一个就是了。转念一想这样太麻烦了,况且题目还要求了不能分配额外的内存了,所以不可行。

在网上研究了别人解题的算法,大概是这样子的。以num(6 5 4 8 7 5 1)举例:

第一步:先从后往前找,8,7,5,1都是降序排列,我们先找到出现升序的那个地方。即num[2]和num[3],此时我们假设index的值为3。

第二步:在num[index]~num[len-1]中找到比num[2]大的最小数。即num[5]。下标记为exchangeIndex。

第三步:交换num[index-1]和num[exchangeIndex]的值。

第四步:重新调整num[index]~num[len-1]为升序序列。

代码如下:

 class Solution {
public:
void nextPermutation(vector<int> &num) {
int index = num.size() - ;
//从右边开始找到第一个不是降序的下标。index值为一对升序数中较大的下标
while(index > ){
if(num[index] > num[index - ]){
break;
}
index--;
}
//如果没有下一个排列,index为0
if(index == ){
sort(num.begin(),num.end());
return ;
}
//在index往后的数字里(降序)找到比[index-1]大的最小的数,下标为exchangeIndex
int exchangeIndex;
for(int i = num.size()-; i >= index; i--){
if(num[i] > num[index-]){
exchangeIndex = i;
break;
}
}
//交换这两个数
swap(num[index-],num[exchangeIndex]);
//index及以后的数字重新按升序排列。
sort(num.begin()+index,num.end()); }
};