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),我们所有的交换和反转操作都是在原数组上直接进行的(原地修改),只使用了几个额外的整型变量,完全符合题意
相关推荐
wuqingshun3141592 小时前
MYSQL的乐观锁和悲观锁是什么?
java
Jerry2 小时前
LeetCode 101. 对称二叉树
算法
唐青枫2 小时前
Java SLF4J 实战指南:从日志门面到 Logback、MDC 和链路追踪
java
jvmind_dev3 小时前
Java GC 实战指南(番外篇):被忽视的隐形杀手 —— Class Unloading 如何拖垮 GC
java·后端
可编程芯片开发3 小时前
基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真
算法
An_s3 小时前
机器学习python之识别图中物品信息
java·linux·开发语言
AI科技星3 小时前
线性算子不是空间映射函数,是全域双螺旋场之间拉伸、旋转、耦合、坍缩的跨空间标准化变换载体《全域数学vs传统数学:人类文明进阶200讲》第80讲
线性代数·算法·矩阵·数据挖掘·回归·乖乖数学·全域数学
米罗篮3 小时前
矩阵快速幂 (Exponentiation By Squaring Applied To Matrices)
c++·线性代数·算法·矩阵
dream_home84073 小时前
图像算法模型NPU适配与算法服务实战指南
人工智能·python·算法·npu 图像服务
AIGS0013 小时前
跨越语义鸿沟:企业本体语义平台的构建与落地
java·人工智能·python·机器学习·人工智能ai大模型应用