题目描述
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 and use only constant 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
本题的意思是输入一个序列,求此序列全排列的下一个序列是什么?题目要求只能在原vector中进行变换,允许使用固定的额外存储(可以理解为不以vector的长度的改变而改变)。同时还给出了一个实例。
思路分析
首先需要了解全排列的序列变化方法才能很好的完成这个题目。
一般的,序列的下一个全排列序列遵循以下算法:
1、序列从左至右依次开始比较,某数遇到的下一个数比某数要大则标记该数。
比如: 2, 1, 4, 6, 3, 5
此时标记1,此时位于序列的第二个位置上。
2、此时再查找已标记的数后面比已标记的数大的集合中最小的数。
比如:2, 1, 4, 6, 3, 5
此时标记3,位于此序列的第四个位置上。
3、利用前面标记的两个位置,对两个位置及中间的数进行倒置。
比如:2, 1, 4, 6, 3, 5
倒置后:2, 3, 6, 4, 1, 5
对于特殊情况:
6, 5, 4, 3, 2, 1
直接转置为:
5, 4, 3, 2, 1, 6
详细代码
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int length = nums.size();
if (length <= 1)
return;
int temp = 0;
int j = 0;
bool flag = true;
int t = 0;
for (int i = length - 1; i >= 1; --i) {
if (nums[i] <= nums[i - 1]) {
t = i;
continue;
}else {
temp = nums[i];
j = i;
flag = false;
break;
}
}
if (!flag) {
if (j == length - 1) {
nums[j] = nums[j - 1];
nums[j - 1] = temp;
}else {
int k = length - 1;
int m = j;
temp = -1;
while (k >= j) {
if (nums[k] > nums[j - 1] ) {
if (temp == -1) {
temp = nums[k];
m = k;
}
else {
if (nums[k] < temp) {
temp = nums[k];
m = k;
}
}
}
k--;
}
nums[m] = nums[j - 1];
nums[j - 1] = temp;
Swap(nums, j, length - 1);
}
return;
}
temp = nums[length - 1];
for (int i = length - 1; i > length - 1 - i; --i) {
temp = nums[i];
nums[i] = nums[length - 1 - i];
nums[length - 1 - i] = temp;
}
return;
}
private:
void Swap(vector<int> & nums, int j, int length) {
for (int i = length; i > j; --i, ++j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
return;
}
};