Leetcode link: https://leetcode.com/problems/next-permutation/
这道题要求不能使用extra memory,所以不能使用递归。下面的算法使用3次扫描解决这个问题,一共4步:
(一) 从右往左扫,找到第一个比前一个元素小的元素,其索引为p;
7 8 9 3 2 1
这里p=1
(二) 从右往左扫,找到第一个比p指向的元素大的元素,其索引为q;
7 8 9 3 2 1
这里q=2
(三) 交换 p 和 q指向的元素;
交换之前:
7 8 9 3 2 1
交换之后:
7 9 8 3 2 1
(四) 把从p+1到数组结束的所有元素倒序。
7 9 1 2 3 8
以下是C++代码,时间复杂度是O(n),空间复杂度是O(1)。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
if (nums.size()<2)
return;
int p = 0;
for (int i = nums.size() - 2; i >= 0; i--) {
if (nums[i]<nums[i + 1]) {
p = i;
break;
}
}
int q = 0;
for (int i = nums.size() - 1; i>p; i--) {
if (nums[i]> nums[p]) {
q = i;
break;
}
}
if (p == 0 && q == 0) {
reverse(nums, 0, nums.size() - 1);
return;
}
int temp = nums[p];
nums[p] = nums[q];
nums[q] = temp;
reverse(nums, p + 1, nums.size() - 1);
}
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--;
}
}
};