问题描述
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
这道题给出一个数列,求大于这个数列的最小数列。
题目问题描述的不是很清楚,这个是字典序排列,其实就是C++STL中next_permutation()库函数,我们的目的就是实现这个函数。
观察数列会发现,如果数列是递减的话我们是找不出比他更大的数列的,所以我们要找到两个递增元素,即从右到左找到第一个左边小于右边的元素,然后我们再找出该元素右边比他大的最小的元素,交换两数,然后再将该数后面的数列reverse()即可。
如果是从左往右也是可以的,那么我们找的就是最后一对递增数列了。
解题思路
举个例子最好说明:给出数列{1,2,4,3,6,5},我们从后往前找,第一对自然是<3,6>了,i,j,k都是代表位置,左边i=3,右边j=6,我们再找i右边的第一个比它大的元素也就是k=5,交换i和k,{1,2,4,5,6,3}再将i后面的数列反转即可{1,2,4,5,3,6}。
class Solution {
public:
void nextPermutation(vector<int> &num) {
int end = num.size() - 1;
int povit = end;
while(povit > 0){
if(num[povit] > num[povit - 1])
break;
povit --;
}
if(povit > 0){
povit --;
int large = end;
while(num[large] <= num[povit])
large --;
swap(num[large] , num[povit]);
reverse(num.begin() + povit + 1 , num.end());
}else{
reverse(num.begin() , num.end());
}
}
};