Next Permutation(31)
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
这个题的意思应该能看懂,就是求全排列中,给定排列的下一个排列,刚开始没有细想,直接从后面开始遍历,当遇到比自己小的数值时就交换位置,后面的进行排序。试了几个样例都对了,于是很开心的提交了。。。leetcode 给出没有通过的例子,我才反应过来,4202320 的next 是4203022,但是我的程序给出的是4220023。
正确的解法:
1.从后向前遍历,找到一个打破递增的位置,例如4202320,0,2,3为递增,2变为递减。
2.然后将该数字与递增序列中大于它,并且最小的数字进行交换。位置后面的直接反转就可以了。(3>2,因此交换位置,变成4203220),将3后的数字反转,得到4203022。得到正解。
至于为啥找升序列,我是这样理解的,升序列是不可能改变数字的位置来变大。只有打破升序才存在可能。剩下的当然是让大于该位置值的最小值,才是最接近原来的排列的。并对后面反转(都是升序,反转就相当于排序)。
void nextPermutation(vector<int>& nums){
int length = nums.size();
int i = length - 1;
int pos = -1;
for (; i >= 0; i--){
if (nums[i] > nums[i - 1]){
pos = i - 1;
break;
}
}
if (pos < 0){
reverse(nums.begin(), nums.end());
return;
}
for (i = length - 1; i > pos; i--){
if (nums[pos] < nums[i]){
int temp = nums[pos];
nums[pos] = nums[i];
nums[i] = temp;
reverse(nums.begin() + pos + 1, nums.end());
return;
}
}
}
祝大家身体健康,学习进步!