具体地,我们这样描述该算法,对于长度为 n 的排列 a:
一(找)、首先从后向前查找第一个顺序对 (i,i+1),满足a[i] < a[i+1]
这样「较小数」即为 a[i]a[i]。此时 [i+1,n) 必然是下降序列。
二(找)、如果找到了顺序对,那么在区间 [i+1,n) 中从后向前查找第一个元素 j 满足 a[i] < a[j]
。这样「较大数」即为 a[j]a[j]。
三(反转)、交换 a[i] 与 a[j]
此时可以证明区间 [i+1,n) 必为降序。我们可以直接使用双指针反转区间 [i+1,n)使其变为升序
,而无需对该区间进行排序。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
// 找到一个较小的i
int i=nums.size()-2;
while(i>=0 && nums[i]>=nums[i+1]){
i--;
}
// 从最后开始找第一个出现的j比i小的数
if(i>=0){
int j=nums.size()-1;
while(j>=0 && nums[j]<=nums[i]){
j--;
}
swap(nums[i],nums[j]);
}
// 对i以后的数反转 反转以后就是排好序的
reverse(nums.begin()+i+1,nums.end());
}
};