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),我们所有的交换和反转操作都是在原数组上直接进行的(原地修改),只使用了几个额外的整型变量,完全符合题意
相关推荐
鱼宵6 小时前
Spring AI 提示词模板:{变量} 参数化 + few-shot,一条提示词反复用
java·人工智能·spring·few-shot·提示词工程·springai
蜗牛互联网6 小时前
Python消费Responses SSE事件:增量文本、超时与取消
java·开发语言·人工智能·后端·python
wanderist.6 小时前
线性筛法详解:从筛质数到欧拉函数、Möbius 函数与约数函数
java·数据结构·算法
All for pursuit.6 小时前
【设计-1】208.实现Trie (前缀树)
数据结构·c++·算法·leetcode
weixin_307779136 小时前
C++代码实现MATLAB中的crossval函数功能
开发语言·c++·算法·matlab
青少儿编程课堂7 小时前
背包问题(0/1 背包与完全背包)解题精讲——动态规划入门
c++·python·算法·bfs·信息学竞赛
光影少年7 小时前
为什么 JavaScript 中 0.1 + 0.2 !== 0.3,如何让其相等?
前端·javascript·算法
Escalating_xu7 小时前
【C 语言】深入理解指针(5):sizeof、strlen、数组名语义与指针笔试题全解析
java·c语言·开发语言
HEJOO97 小时前
Linux 设备驱动系列——使用全局工作队列
java·linux·算法
谢亮_vipxieliang7 小时前
Go Channel 高级模式——从底层原理到扇出扇入实战
java·数据库·golang