🧩Algo 技巧

31. 下一个排列

难度:🟡 Medium | 标签:数组、双指针 | 状态:⬜ LeetCode 链接

思路

  1. 从右往左找第一个 nums[i] < nums[i+1] 的 i(这是要被替换的点)
  2. 从右往左找第一个 > nums[i] 的 j,与 i 交换
  3. 反转 i+1 之后的部分

如果没有 i(整体降序),直接反转整个数组。

代码

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size();
        int i = n - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) --i;
        if (i >= 0) {
            int j = n - 1;
            while (nums[j] <= nums[i]) --j;
            swap(nums[i], nums[j]);
        }
        reverse(nums.begin() + i + 1, nums.end());
    }
};

复杂度

  • 时间 O(n),空间 O(1)

易错 / 回顾

  • 第二步用 <= 找严格大的(重复值时跳过相等)
  • 反转的起点是 i + 1,i = -1 时反转整个数组
  • 与全排列(46)不同:本题原地变下一个,46 是穷举
Related · 技巧