力扣第三十一题——下一个排列

内容介绍

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

  • 例如,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 <= nums.length <= 100
  • 0 <= nums[i] <= 100

完整代码

 void swap(int *a, int *b) {int t = *a;*a = *b, *b = t;
}
void reverse(int *nums, int left, int right) {while (left < right) {swap(nums + left, nums + right);left++, right--;}
}void nextPermutation(int *nums, int numsSize) {int i = numsSize - 2;while (i >= 0 && nums[i] >= nums[i + 1]) {i--;}if (i >= 0) {int j = numsSize - 1;while (j >= 0 && nums[i] >= nums[j]) {j--;}swap(nums + i, nums + j);}reverse(nums, i + 1, numsSize - 1);
}

思路详解

  1. swap函数:这是一个辅助函数,用于交换两个整数的值。它接收两个整数的指针作为参数,通过临时变量t来实现两个整数的交换。

  2. reverse函数:这是一个辅助函数,用于反转数组中指定范围的元素。它接收数组的指针、左边界索引和右边界索引作为参数。通过头尾元素交换的方式,将数组指定范围内的元素进行反转。

  3. nextPermutation函数:这是主函数,用于生成给定数组的下一个排列。以下是详细步骤:

    a. 从后向前查找第一个相邻升序的元素对(即找到第一个nums[i] < nums[i + 1]的位置)。如果不存在这样的元素对,说明当前数组是最大的排列,直接反转整个数组即可得到最小的排列。

    b. 在步骤a找到的元素nums[i]之后,从后向前查找第一个大于nums[i]的元素nums[j]

    c. 交换nums[i]nums[j]的值。

    d. 反转nums[i + 1]nums[numsSize - 1]的元素,使得这部分元素按升序排列。

下面通过一个示例来具体说明这个过程:

假设数组为:1 2 3 4 3 2 1

步骤a:从后向前查找,找到nums[3] = 4nums[4] = 3,满足nums[i] < nums[i + 1],因此i = 3

步骤b:在nums[i + 1]nums[numsSize - 1]范围内,找到第一个大于nums[i]的元素,即nums[6] = 1

步骤c:交换nums[3]nums[6],数组变为:1 2 3 1 3 2 4

步骤d:反转nums[4]nums[6]的元素,数组变为:1 2 3 1 2 3 4

最终得到的数组1 2 3 1 2 3 4就是原数组1 2 3 4 3 2 1的下一个排列。

知识点精炼

一、指针与地址操作

  1. 指针:一种特殊变量,用于存储变量地址。
  2. 解引用:通过指针访问其所指向的变量,使用操作符 *

二、函数定义与调用

  1. 函数定义:使用 return_type function_name(parameters) 语法声明函数。
  2. 函数参数:通过指针传递地址,实现对原始数据的修改。

三、数组操作

  1. 数组元素访问:通过索引和指针运算访问数组元素。
  2. 数组区间操作:通过循环和指针操作实现对数组的区间操作。

四、算法逻辑

  1. 排列生成:通过交换和反转操作生成数组的下一个排列。
  2. 双指针技巧:使用两个指针分别从前后遍历数组,提高查找效率。

五、循环与条件判断

  1. while 循环:在不确定循环次数时,使用 while 循环实现条件控制。
  2. if-else 判断:根据条件执行不同的代码块。

六、代码优化

  1. 代码简洁性:通过逗号表达式和简洁的赋值语句减少代码行数。
  2. 减少不必要的操作:在循环和条件判断中,尽量减少不必要的计算和比较。

以下是具体知识点与代码的对应关系:

  • swap 函数:涉及指针解引用和临时变量交换。
  • reverse 函数:使用双指针技巧,通过头尾元素交换实现数组反转。
  • nextPermutation 函数:实现排列生成的算法逻辑,包括查找降序对、交换元素和反转数组区间。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/875336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis详解--springboot整合redis

1. java连接redis 思考: 我们之前操作redis都是通过命令行的客户端来操作。 在开发时都是通过java项目操作redis.引入Redis依赖 <!--引入java连接redis的驱动--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactI…

ThreadLocal面试三道题

针对ThreadLocal的面试题&#xff0c;我将按照由简单到困难的顺序给出三道题目&#xff0c;并附上参考答案的概要。 1. 简单题&#xff1a;请简述ThreadLocal是什么&#xff0c;以及它的主要作用。 参考答案&#xff1a; ThreadLocal是Java中的一个类&#xff0c;用于提供线…

力扣笔试题系列(一)

1、给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 char * mergeAlternately(char * word1, char * word2){int len1 strlen(word1);i…

C++ primer plus 第16章string 类和标准模板库, 无序关联容器(C++11)

C primer plus 第16章string 类和标准模板库, 无序关联容器(C11) C primer plus 第16章string 类和标准模板库, 无序关联容器(C11) 文章目录 C primer plus 第16章string 类和标准模板库, 无序关联容器(C11)16.4.5 无序关联容器(C11) 16.4.5 无序关联容器(C11) 无序关联容器是…

【常微分方程】

框架 常微分方程的概念一阶微分方程可变离分量齐次方程一阶线性微分方程可降阶的高阶微分方程二阶常系数齐次线性微分方程二阶常系数非齐次线性微分方程 讲解 【1】 常微分方程&#xff1a;是微分方程的特殊情况&#xff1b; 阶&#xff1a;是方程未知函数的最高阶导数的阶数&…

力扣138【随机链表的复制】

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 ne…

【.NET全栈】ASP.NET开发Web应用——ASP.NET数据绑定技术

文章目录 前言一、绑定技术基础1、单值绑定2、重复值绑定 二、数据源控件1、数据绑定的页面生存周期2、SqlDataSource3、使用参数过滤数据4、更新数据和并发处理5、编程执行SqlDataSource命令6、ObjectDataSource控件介绍7、创建业务对象类8、在ObiectDataSource中使用参数9、使…

06 ES6中的Map类型

ES6 中的 Map 是一种集合数据结构&#xff0c;与 Set 类似&#xff0c;但它是用来存储键值对的。Map 提供了更灵活的迭代和更广泛的键类型支持&#xff0c;与普通的对象相比&#xff0c;Map 的键可以是任何值&#xff0c;包括对象和函数。 以下是 Map 类型的一些关键特性和常用…

ElementUI,修改el-table中的数据,视图无法及时更新

需求&#xff1a;点击table表格中的“修改”之后&#xff0c;当前行变为可输入状态的行&#xff0c;点击“确定”后变为普通表格&#xff1b; 先贴上已经完美解决问题的代码 实现代码&#xff1a; <section><div style"display: flex;justify-content: space-b…

爬虫学习1:初学者简单了解爬虫的基本认识和操作(详细参考图片)

爬虫 定义&#xff1a;爬虫&#xff08;Web Crawler 或 Spider&#xff09;是一种自动访问互联网上网页的程序&#xff0c;其主要目的是索引网页内容&#xff0c;以便搜索引擎能够快速检索到相关信息。以下是爬虫的一些关键特性和功能&#xff1a; 自动化访问&#xff1a;爬虫能…

【React】事件绑定:深入解析高效处理用户交互的最佳实践

文章目录 一、什么是事件绑定&#xff1f;二、基本事件绑定三、绑定 this 上下文四、传递参数五、事件对象六、事件委托七、常见事件处理八、优化事件处理 React 是现代前端开发中最受欢迎的框架之一&#xff0c;其组件化和高效的状态管理能力使得构建复杂的用户界面变得更加容…

嵌入式MCU固件的几种Flash划分方式详解

通过OTA远程等方式下载的程序,其实还需要提前下载bootloader程序,才能进一步下载APP程序。 今天就来说说通过OTA方式升级固件时,几种flash划分方式。 独立型 所谓独立型就是专门划出一部分闪存(Flash)空间用来存储引导程序(BootLoader)。 如下图: BootLoader:引导…

神经网络的发展历程及未来展望

神经网络的发展历程及未来展望 神经网络&#xff0c;作为人工智能和机器学习领域的核心技术之一&#xff0c;经历了多次起伏波动&#xff0c;每一次的高潮和低谷都深刻影响了该技术的发展轨迹和应用范围。本文将详细探讨神经网络的发展历程&#xff0c;包括其爆发期、低谷期&am…

linux快速入门-学习笔记

linux快速入门-学习笔记 第一章&#xff1a;Linux系统概念及命令学习Linux系统基本概念命令终端介绍命令格式介绍Linux系统辨别目录与文件的方法通过文件详细属性辨别ls 查看目录/文件命令Linux 系统下的归属关系命令行编辑技巧Linux 基本权限的类别课后练习 第二章&#xff1a…

扫地机器人离线语音识别芯片,工业级智能交互ic,NRK3301

随着科技的飞速发展&#xff0c;智能家居已成为人们追求高品质生活的新趋势。扫地机器人&#xff0c;作为智能家居的重要一员&#xff0c;正逐步从简单的清扫工具进化为具备高度智能的家居助手。 在这一背景下&#xff0c;离线语音识别技术显得尤为重要。传统的扫地机器人大多依…

问题记录-Spring Security- bean httpSecurity not found

问题描述 最近使用Security的时候报了下面的错误&#xff1a; 配置如下&#xff1a; EnableWebSecurity Slf4j public class SecurityConfig {Resourceprivate CustUserService custUserService;Beanpublic AuthenticationProvider authenticationProvider() {return new A…

element-plus时间组件el-date-picker只能选择当前及之前日期

<el-date-picker v-model"timeVal" type"daterange" value-format"YYYY-MM-DD" range-separator"To" start-placeholder"开始时间" end-placeholder"结束时间" />默认是这样的&#xff0c;需要绑定disabled…

如何预防网站爬虫攻击

网站爬虫&#xff08;Web Scrapers&#xff09;是一种自动化工具&#xff0c;用于抓取网页上的数据。虽然合法的搜索引擎爬虫有助于提升网站的可见度&#xff0c;但恶意爬虫可能带来数据盗窃、版权侵犯等问题&#xff0c;甚至造成服务器过载。本文将探讨如何有效预防网站受到恶…

学习笔记4:docker和k8s选择简述

docker和 k8s 占用资源 使用客户体量Docker 和 Kubernetes&#xff08;K8s&#xff09;都是流行的容器化技术&#xff0c;但它们在资源管理和使用上有一些不同。以下是关于两者资源占用和使用客户体量的详细比较&#xff0c;基于具体数据和信息&#xff1a; Docker 资源占用…

一款基于Cortex-M0+的单片机音频编解码 - CJC2100

USBCodec芯片可以对数字音频信号进行多种处理&#xff0c;例如增加音量、均衡调节、音效处理等。这些处理可以通过耳机的控制按钮来实现&#xff0c;让用户可以根据自己的喜好来调整音频效果。USBCodec芯片还可以控制噪声和失真的水平&#xff0c;以提供高品质的音频输出。噪声…