LeetCode-31-下一个排列

【LeetCode】 下一个更大的排列(数组) …今天做了一道挺有意思的题目,leetcode原题描述如下: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,... 阅读详情

题目

来源:LeetCode.

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。
例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。
更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,
那么数组的 下一个   排列 就是在这个有序容器中排在它后面的那个排列。
如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。
必须 原地 修改,只允许使用额外常数空间。

示例 1:

输入:nums = [1,2,3]
输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]
输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]
输出:[1,5,1]

提示:

  • 1 < = n u m s . l e n g t h < = 100 1 <= nums.length <= 100 1<=nums.length<=100
  • 0 < = n u m s [ i ] < = 100 0 <= nums[i] <= 100 0<=nums[i]<=100

接下来看一下解题思路:

思路:两遍扫描:

    将给定数字序列重新排列成字典序中下一个更大的排列。

    以数字序列 [ 1 , 2 , 3 ] [1,2,3] [1,2,3] 为例,其排列按照字典序依次为:

[ 1 , 2 , 3 ] [ 1 , 3 , 2 ] [ 2 , 1 , 3 ] [ 2 , 3 , 1 ] [ 3 , 1 , 2 ] [ 3 , 2 , 1 ] [1,2,3]\\ [1,3,2]\\ [2,1,3]\\ [2,3,1]\\ [3,1,2]\\ [3,2,1] [1,2,3][1,3,2][2,1,3][2,3,1][3,1,2][3,2,1]

这样,排列 [ 2 , 3 , 1 ] [2,3,1] [2,3,1] 的下一个排列即为 [ 3 , 1 , 2 ] [3,1,2] [3,1,2]。特别的,最大的排列 [ 3 , 2 , 1 ] [3,2,1] [3,2,1] 的下一个排列为最小的排列 [ 1 , 2 , 3 ] [1,2,3] [1,2,3]。

    希望找到一种方法,能够找到一个大于当前序列的新序列,且变大的幅度尽可能小。具体地:
    需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。
    同时我们要让这个「较小数」尽量靠右,而「较大数」尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

以排列 [ 4 , 5 , 2 , 6 , 3 , 1 ] [4,5,2,6,3,1] [4,5,2,6,3,1] 为例:
    能找到的符合条件的一对「较小数」与「较大数」的组合为 2 2 2 与 3 3 3,满足「较小数」尽量靠右,而「较大数」尽可能小。
    当完成交换后排列变为 [ 4 , 5 , 3 , 6 , 2 , 1 ] [4,5,3,6,2,1] [4,5,3,6,2,1],此时可以重排「较小数」右边的序列,序列变为 [ 4 , 5 , 3 , 1 , 2 , 6 ] [4,5,3,1,2,6] [4,5,3,1,2,6]。

具体地,这样描述该算法,对于长度为 n n n 的排列 a a a:
  1. 从后向前查找第一个顺序对 ( i , i + 1 ) (i, i + 1) (i,i+1), 满足 a [ i ] < a [ i + 1 ] a[i] < a[i + 1] a[i]<a[i+1],
    (如果不存在,说明当前序列已经是降序序列,即最大序列,直接用步骤 3 3 3,得到最小的升序序列),
    这样较小数即为 a [ i ] a[i] a[i],此时 [ i + 1 , n ) [i + 1, n) [i+1,n) 必然是下降序列;
  2. 如果找到了顺序对,那么在区间 [ i + 1 , n ) [i + 1, n) [i+1,n) 中从后向前找到第一个元素 j j j, 满足 a [ i ] < a [ j ] a[i] < a[j] a[i]<a[j]。这样较大数即为 a [ j ] a[j] a[j]
  3. 交换 a [ i ] a[i] a[i] 与 a [ j ] a[j] a[j],此时区间 [ i + 1 , n ) [i + 1, n) [i+1,n) 必为降序,可以使用双指针反转区间,使其变为升序;
public static void nextPermutation(int[] nums) {
    if (nums == null || nums.length <= 0) {
        return;
    }

    int i = nums.length - 2;

    // 从后往前寻找第一个满足 a[i] < a[i + 1] 的顺序对
    while (i >= 0 && nums[i] >= nums[i + 1]) {
        --i;
    }

    if (i >= 0) {
        int j = nums.length - 1;
        // 在 [i + 1, n) 区间,从后往前找第一个元素 j, 满足 a[i] < a[j]
        // 能走到这,说明一定存在一个满足条件的 j,所以不用担心 j 下标越界
        while (nums[i] >= nums[j]) {
            --j;
        }
        // 交换 i 和 j
        swap(nums, i, j);
    }
    // 反转 [i + 1, n) 区间的序列
    reverse(i + 1, nums);
}

private static void swap(int[] nums, int i, int j) {
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}

private static void reverse(int left, int[] nums) {
    int right = nums.length - 1;
    while (left < right) {
        swap(nums, left, right);
        ++left;
        --right;
    }
}
复杂度分析

时间复杂度: O ( N ) O(N) O(N),其中 N N N 为给定序列的长度。我们至多只需要扫描两次序列,以及进行一次反转操作。

空间复杂度: O ( 1 ) O(1) O(1),只需要常数的空间存放若干变量。

【中等】力扣算法题解析LeetCode31:下一个排列 本文介绍了如何找到整数数组的下一个字典序更大的排列。算法步骤如下: 从右向左找到第一个下降的位置i; 若存在i,再从右向左找到第一个大于nums[i]的位置j; 交换i和j位置的元素; 反转i+1到末尾的子数组使其升序排列。整体时间复杂度O(n),空间复杂度O(1)。通过原地修改数组,实现了高效查找下一个排列。 阅读详情

相关推荐

LeetCode 31 - 下一个排列

是一个经典题,考察对排列的基本操作,包括逆序、排序以及贪心思想。该题目常会出现在竞赛、面试中,变体场景也非常多,例如字典序排列的生成、排列搜索问题等。以下是详细解法、分析以及变体分类。实现获取下一个排列的算法,该排列是字典序中比当前排列大的下一个排列。

互联网架构师笔记 538

力扣(LeetCode)31. 下一个排列(2022.01.31)

 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。  例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。  整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。 例如,arr

ChaoYue_miku的博客 2399

基于大模型的急性重症胰腺炎全流程预测与诊疗方案研究

本研究构建了基于大模型的急性重症胰腺炎(SAP)全流程预测与诊疗系统,实现了从术前风险评估到术后康复管理的精准诊疗闭环。通过整合临床信息、实验室检查和影像学等多源数据,模型在测试集上预测准确率达X%,AUC为X,显著优于传统评分系统。研究创新性地将预测结果应用于手术方案制定、麻醉决策、并发症防控及个性化护理,形成智能化诊疗方案。验证结果显示模型具有良好的稳定性和临床适用性,同时配套的健康教育体系提升了患者自我管理能力。尽管存在样本局限性和模型可解释性等不足,该研究为SAP的精准诊疗提供了新范式,未来可通过扩

嵌入式毕设/课设资料清单(速查手册·文档模板·题库,持续更新)→ 见最新文章 1115

【下一个排列】

输入: 输出:输入: 输出:输入: 输出:-好不容易理解了这道题要我干啥,但是没有思路!假设我们有一群人在排队买东西,每个人身上都贴着一个数字,这些人按照身上数字的顺序站成一排,就形成了一个数字排列,就好比题目中的整数数组。好的,以下是用一个通俗的比喻来解释“下一个排列”的思路:假设我们有一群人在排队买东西,每个人身上都贴着一个数字,这些人按照身上数字的顺序站成一排,就形成了一个数字排列,就好比题目中的整数数组。比如说,队伍是这样排的:3、2、5、4、1,我们从后往前看,就会发现4比1高,但是再往前看,5比

weixin_47868976的博客 1160

解决fetch_california_housing数据集403错误的3种实用方法(附手动下载地址)

本文针对机器学习中常见的fetch_california_housing数据集403 Forbidden错误,提供了三种实用的解决方案。从理解HTTP 403错误的根源出发,详细介绍了修改源码路径、使用国内镜像源以及手动下载并配置数据文件这三种方法,并附带了可靠的手动下载地址,帮助开发者彻底解决数据加载障碍,确保机器学习项目顺利进行。

weixin_29062963的博客 559

WinCC与PLC在西门子逻辑赛项中的通信配置避坑指南

本文针对西门子逻辑赛项中WinCC与PLC通信配置的常见问题,提供了一套实战避坑指南。重点解析了WinCC、PLC与EET仿真平台的三角通信架构,强调了IP地址规划、防火墙设置等关键环节的注意事项,并给出了系统化的故障诊断流程与排查技巧,帮助选手和技术人员快速定位并解决通信故障,确保监控系统稳定运行。

weixin_29165725的博客 107

leetcode31下一个更大的排列

题目:Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement

qq_27736687的博客 405

Rust 与 C/C++:Rust 比 C/C++ 更好还是只是“技能问题”?

对于许多嵌入式系统开发人员而言,的崛起似乎掀起了一股不小的浪潮,特别是在相较于传统的语言,Rust的“内存安全”优势让人眼前一亮。然而,是否可以将Rust作为C/C++的替代品?或者说,Rust是否真的比C/C++更好,抑或它只是一个“技能问题”呢?在嵌入式开发的领域,我观察到,尽管Rust在一些高性能、内存安全敏感的场景中受到了广泛推崇,但它在实际应用中的普及度,特别是在嵌入式领域,依然有限。今天,我会从多个角度探讨这个问题,并且分享一些对于Rust、C/C++以及嵌入式系统开发的个人见解。

qq_63315166的博客 1300

【理解题意】next permutation 下一个字典序更大的排列

求下一个字典序更大的排列。 大致思路: 需要理解题意。 其实对于数字的序列来说,只关注2个数,其实要么是升序,要么是降序,要么是相等。这里不用考虑相等了,因为相等的话字典序也一样,那么就看如果原来是降序,比如1 3 2 1中后三个是降序,下一个字典序更大的排列是2 1 13,应该怎么求出来呢?可以发现,先把后三个降序的排成升序,但显然1 1 2 3的字典序是小于原来的1 3 2 1的,...

It's the Climb 1101

汽车Bootloader流程

根据ISO14229-1 写的汽车行业 Bootloader流程 1:编程前 → 先读取软硬件版本号 22 F1 XX 软件信息 22 F1 XX 硬件信息 → 进入扩展会话extend diagnostic sessions 功能寻址 10 03 → 编程条件检测routine control:ECU升级条件的判断,如车速,检测车的型号 31 01 02 03 → 关闭DTC检测,(由于很多节点收不到其它节点的报文后会记录DTC故障)功能寻址 85 02 → 关闭诊断通讯(禁止各个节点的应用报...

weixin_41320142的博客 2829

1104全部报表版本号-银监会报表

G4B_Ⅲ(a)X1《与非中央交易对手的衍生具交易对手信用风险违约风险计算表(现期风险暴露法)(第一档)》G4B_Ⅲ(b)X1《与非中央交易对手的证券融资交易对手信用风险违约风险计算表(权重法)(第一档)》G4B_Ⅲ(a1)X2《与非中央交易对手的衍生具交易对手信用风险违约风险计算表(标准法)(第二档)》Ⅲ(a)X2《与非中央交易对手的衍生具交易对手信用风险违约风险计算表(现期风险暴露法)(第二档)》Ⅲ(a1)X1《与非中央交易对手的衍生具交易对手信用风险违约风险计算表(标准法)(第一档)》

数字化老司机 6285

【力扣LeetCode】31 下一个排列

题目描述(难度中) 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 链接 https://leetcode-...

Jiewang的博客 414

数据资产入表——解读100页数据资产入表解读与分析【附全文阅读】

本文档《数据资产入表:解读与分析》面向企业财务、数据管理、法务合规及高管等核心岗位,系统解析数据资产入表全流程。以"政策-实操-价值"为主线,首先解读入表政策要求,明确会计处理规范;其次详细拆解数据盘点、治理、确权、评估等实操步骤,提供行业案例参考;最后分析入表难点及后续运营策略,为企业提供从政策理解到落地执行的一站式解决方案。

cdfunlove的博客 389

力扣LeetCode 31.下一个排列

摘要:本文介绍了如何找出整数数组的下一个字典序排列。算法思路是从后往前找到第一个下降的元素,将其与后面恰好比它大的元素交换,然后对后续元素升序排序。若已是最大排列,则反转整个数组。解法时间复杂度为O(n),空间复杂度O(1)。示例展示了[1,2,3]→[1,3,2],[3,2,1]→[1,2,3]等转换过程。

2301_80470756的博客 55

基于Spring Boot 3 + Vue 3 + Vite的现代化社区订餐系统设计与实现

本文将详细阐述系统的整体架构、数据库设计、核心功能模块(用户管理、餐厅管理、菜品浏览、购物车、订单管理)的实现细节,并提供关键代码示例。<el-input v-model="loginForm.password" type="password" placeholder="密码" prefix-icon="Lock" show-password />.requestMatchers("/api/auth/**", "/api/dishes/public/**").permitAll() // 公开接口。

2201_76125393的博客 468

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

力扣LeetCode #31 下一个排列(NextPermutation)

- 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须原地修改,只允许使用额外常数空间。 来源:LeetCode - 示例 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 1,2,4,3 → 1,3,2,4 1,2,5,4,6,3 → 1,2,5,6,3,4 - 思路分析 刚开始看了测试用例,只考虑

weixin_49155948的博客 245

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

#力扣LeetCode31. 下一个排列 @FDDLC

题目描述: 31. 下一个排列 - 力扣(LeetCode) (leetcode-cn.com) 自测用例: [1,2,3] [3,2,1] [1,1,5] [1] [1,3,2] [2,1,3] [2,3,1] [3,1,2] [2,3,1] [1,3,2] [2,2,1] [3,1,4,1,5,9,2,6] [1,2,3] [3,2,1] [1,1,1] [2,2,1] [3,1,4,1,5,9,2,6,3,9,1,10,33,10,37,100,3,38,22,19,30,1,2,3,4,

LiuXingchang的博客 390

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【算法入门】LeetCode 31:下一个排列 - 掌握字典序的奥秘(Java & JavaScript)|# 力扣31. 下一个排列题解:Java与JavaScript双实现详解

LeetCode 31:下一个排列 问题描述 给定一个整数数组,找出其下一个字典序更大的排列。若已是最大排列,则返回最小排列。 解题思路 找逆序点:从后向前找到第一个满足 nums[i] < nums[i+1] 的索引 i 找交换点:在 i 右侧找到最小的大于 nums[i] 的值 nums[j] 交换元素:交换 nums[i] 和 nums[j] 反转后半:反转 i+1 到末尾的子数组 复杂度 时间 O(n),空间 O(1) 核心代码 void nextPermutation(int[] nums)

南北极之间 898

力扣31题-下一个排列

力扣31题-下一个排列

m0_65818274的博客 247

《LeetCode力扣练习》第31题 下一个排列 Java

《LeetCode力扣练习》第31题 下一个排列 Java 一、资源 题目: 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列

XRT_knives的博客 278

力扣第31题:下一个排列

学习目标: 力扣第31题:下一个排列 学习内容: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/next-p

童一的博客 430

LeetCode31-下一个排列

LeetCode31-下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 一、思路 (一)移动数 ...

lyd1995的博客 251

31. 下一个排列 - 力扣(LeetCode)

整数数组的一个就是将其所有成员以序列或线性顺序排列。arr[1,2,3][1,3,2][3,1,2][2,3,1]整数数组的是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。[1,3,2][3,1,2][1,2,3][3,2,1]给你一个整数数组nums,找出nums的下一个排列。必须。

Dubhehug的博客 943

LeetCode--31.下一个排列

那我们就将前面我们根本用不到的数给切掉,只考虑后面的数,那就新形成了一个数组嘛,我们就求这个数组的下一排列,是不是就简化了一下,反正求下一排列,前面那些权重比较大的数也动不得。当我们找到前面的数(p2)比后面的数(p1)小的那个位置的时候,我们就将前面的数(p2)依次与后面的所有的数(>=p1)相比较,找到一个最接近的数,与前面的数(p2)交换位置,再对。你可能有疑惑,是啊,我找出来了,但是,为什么要将前面的数(p2)与它后面的所有的数相比较,找出最接近它的数并且要比前面的数大呢?没有,也没关系,我会说。

dying_man的博客 1545

java学习 leetcode31 下一个排列

寻找降序对:从后向前找到第一个降序的位置,确保能找到一个比当前位置大的元素进行交换。寻找交换元素:在降序部分中找到刚好大于当前元素的值进行交换,保证新排列是下一个更大的排列。反转操作:将降序部分反转成升序,使得这部分成为最小的排列,从而保证整个数组是下一个字典序排列。

qq_64012735的博客 800

力扣31 下一个排列

寻找下一个排列

dastatham的博客 498
上一篇: LeetCode-30-串联所有单词的子串
下一篇: LeetCode-32 - 最长有效括号
CodAlun
博客等级 码龄8年 46粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值