题目
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
分析
关于字典序的概念其实我并不是很清楚,所以首先从小到大列出了{1,2,3}的6中排列方式,总结了其变化规律,具体见代码。
实现一
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n=nums.size();
if(n<2) return;
int i=n-2, j;
while(i>=0){
int j=n-1;
while(j>i && nums[i]>=nums[j])
j--;
if(j>i){
swap(nums[i], nums[j]);
sort(nums.begin()+i+1, nums.end());
break;
}
i--;
}
if(i<0)
sort(nums.begin(), nums.end());
}
};
思考一
本来也不打算重构了,虽然代码有点丑。但是后面看题解发现有O(n)的解法,决定还是搞一搞。
一个是由后往前搜索大数的时候如果前一次不成功,就已经保证了之前的数字是降序的,利用这个可以较少比较次数。另外sort也是不必要的,swap之后的子数组保证了是降序的,直接reverse成升序就行了。
实现二
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n=nums.size();
if(n<2) return;
int i=n-2;
while(i>=0 && nums[i]>=nums[i+1])
i--;
if(i<0){
reverse(nums.begin(), nums.end());
}
else{
int j=n-1;
while(nums[j]<=nums[i])
j--;
swap(nums[i], nums[j]);
reverse(nums.begin()+i+1, nums.end());
}
}
};
思考二
提交通过之后发现成绩并没有提高。。。我的内心是崩溃的,只能说这个平台很诡异。。。