这道题目,更像一道数学题,解题思路分为4步。
1) 从右向左进行扫描,找到第一个比它前一个元素更小的元素,当前元素的位置,记作p。
4 5 6 3 2 1 | p2) 从右向左进行扫描,找到第一个比p位置元素大的元素,当前元素的位置,记作q。
4 5 6 3 2 1 | q
3) 交换p和q
4 5 6 3 2 1 swap 4 6 5 3 2 1
4) 反转[p+1, nums.length-1]内的元素
4 6 1 2 3 5
代码如下:
class Solution {
private:
void reverse(vector<int>& nums, int left, int right){
while(left<right){
int temp = nums[left];
nums[left]=nums[right];
nums[right]=temp;
left++;
right--;
}
}
public:
void nextPermutation(vector<int>& nums) {
int len = (int)nums.size();
if(len<2)
return;
int p=0;
for(int i=len-2; i>=0; i--){ // 计算p
if(nums[i]<nums[i+1]){
p=i;
break;
}
}
int q = 0;
for(int i=len-1; i>p; i--){ // 计算q
if(nums[i]>nums[p]){
q=i;
break;
}
}
if(p==0 && q==0){ // 特殊情况,序列已经降序排列
reverse(nums, 0, len-1); // 反转
return;
}
int temp=nums[p];
nums[p]=nums[q];
nums[q]=temp;
reverse(nums, p+1, len-1); // 反转,其实这里也可以写为reverse(nums.begin()+p+1, nums.end()),前提是加上头文件<algorithm>
}
};