給定整數數組,原地修改為字典序下一個排列。若不存在(已是最大排列),重置為最小排列(升序)。要求 O(1) 額外空間。
a[i] < a[i+1] 的位置 i(逆序對邊界)a[j] > a[i] 的位置 ja[i] 和 a[j]i+1 到末尾的子數組(使其升序,即最小)class Solution {
public:
void nextPermutation(vector& nums) {
int n = nums.size(), i = n - 2;
// 1. 找逆序對邊界
while (i >= 0 && nums[i] >= nums[i+1]) i--;
if (i >= 0) {
// 2. 找右側比 nums[i] 大的最小元素(實際是從右找第一個大的)
int j = n - 1;
while (nums[j] <= nums[i]) j--;
swap(nums[i], nums[j]);
}
// 3. 反轉後綴
reverse(nums.begin() + i + 1, nums.end());
}
};
1 2 3 → i=1 (2<3), j=2 (3>2), swap→1 3 2, reverse 後綴(單元素)→1 3 2 3 2 1 → i=-1 (全降序), 直接 reverse→1 2 3 1 1 5 → i=1 (1<5), j=2 (5>1), swap→1 5 1, reverse 後綴→1 5 1
O(n),單次掃描 + 反轉O(1),原地修改reverse 等價於對降序後綴排序升序