LeetCode 31
https://leetcode.cn/problems/next-permutation/description/
难度:中等
- 从右向左,找第一个小于右侧相邻数字的数 x
- 找 x 右边最小的大于 x 的数 y,交换 x 和 y
- 反转 y 右边的数,把右边的数变成最小的排列
时间复杂度:O(n),其中 n 是 nums 的长度。最坏情况下需要遍历整个 nums 数组。
空间复杂度:O(1)。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size();
// 第一步:从右向左找到第一个小于右侧相邻数字的数 nums[i]
int i = n - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
// 如果找到了,进入第二步;否则跳过第二步,反转整个数组
if (i >= 0) {
// 第二步:从右向左找到 nums[i] 右边最小的大于 nums[i] 的数 nums[j]
int j = n - 1;
while (nums[j] <= nums[i]) {
j--;
}
// 交换 nums[i] 和 nums[j]
swap(nums[i], nums[j]);
}
// 第三步:反转 nums[i+1:](如果上面跳过第二步,此时 i = -1)
reverse(nums.begin() + i + 1, nums.end());
}
};