31.下一个排列

题目描述

题目描述

思路

思路

代码

java 复制代码
class Solution {
    public void nextPermutation(int[] nums) {
        int i = nums.length - 2;
        
        // 1. 从后往前找第一个相邻的升序对 (nums[i] < nums[i+1])
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        
        // 如果 i >= 0,说明找到了这样的数字,需要进行交换
        // 如果 i < 0,说明整个数组是降序的,直接跳过交换步骤,进行全部反转即可
        if (i >= 0) {
            int j = nums.length - 1;
            // 2. 从后往前找第一个大于 nums[i] 的数字 nums[j]
            while (j > i && nums[j] <= nums[i]) {
                j--;
            }
            // 3. 交换 nums[i] 和 nums[j]
            swap(nums, i, j);
        }
        
        // 4. 将 i 之后的序列反转,使其变为升序(字典序最小)
        reverse(nums, i + 1);
    }
    
    // 辅助方法:交换数组中两个元素
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    
    // 辅助方法:反转数组中从 start 开始到末尾的部分
    private void reverse(int[] nums, int start) {
        int left = start, right = nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left++;
            right--;
        }
    }
}

复杂度分析

  • 时间复杂度:O(N)O(N)O(N),其中 NNN 是数组的长度。我们最多只需要遍历数组两次(一次找 i,一次找 j),然后再反转一次数组末尾部分
  • 空间复杂度:O(1)O(1)O(1),我们所有的交换和反转操作都是在原数组上直接进行的(原地修改),只使用了几个额外的整型变量,完全符合题意
相关推荐
ch.ju1 小时前
Java Programming Chapter 4——Private attribute
java·开发语言
许彰午1 小时前
12_ArrayList与LinkedList深度对比
java·前端·python
凌波粒1 小时前
LeetCode--98.验证二叉搜索树(二叉树)
算法·leetcode·职场和发展
Misnearch1 小时前
3635. 最早完成陆地和水上游乐设施的时间II
leetcode·贪心·排序
C+++Python1 小时前
如何在 Java 中使用 BIO、NIO 和 AIO?
java·开发语言·nio
Kurisu5752 小时前
深度拆解:从令牌桶到滑动窗口,高并发系统限流算法的数学本质与边界
java·网络·算法
哈泽尔都2 小时前
运动控制教学——5分钟学会力控算法(阻抗/导纳/力位混合)
c++·python·算法·决策树·贪心算法·机器人·gpu算力
WWW65262 小时前
代码随想录 打卡第四十七天
数据结构·算法·leetcode