【LeetCode笔记】31. 下一个排列(Java、原地算法、偏数学)
文章目录
- 题目描述
- 思路 && 代码
- 二刷
打卡第八天~
题目描述
- 需要花点时间思考的一道题,这篇题解写得很好。
思路 && 代码
- 主要分为这三个步骤:
- 从后往前找到满足 nums[first] < nums[first + 1] 的索引 first
- 从后往前找到满足 nums[second] > nums[first] 的索引 second
- 交换 nums[first]、nums[second],翻转 nums[ first + 1 : ]
- 对于步骤1,找不到 first 时翻转整个数组,也就是当前排列为最大排列的情况。
- 对于步骤2,nums[second] 一定是最接近 nums[first] 的值(可以证明)
- 步骤3进行交换后,有 nums[first + 1 : ] 满足 nums[i] > nums[i + 1],即当前排列为nums[first + 1 : ] 的最大排列;那么对nums[first : ]进行一个翻转,即可得到 nums[first : ]的最小排列,也就是最接近初始排列的下一个排列。
- 借用leetcode 题解区 powcai 大佬的例子:
- 对于 nums = [1, 2, 7, 4, 3, 1]
- 找到 nums[first] = nums[1] = 2
- 找到 nums[second] = nums[4] = 3
- 交换 nums = [1, 3, 7, 4, 2, 1](可以看到 7 4 2 1 是刚好降序排列的)
- 翻转 nums = [1, 3, (1, 2, 4, 7)] (刚好变成 1, 3 开头的最小排列,是1, 2 排列的最大排列的下一个排列)
- 复杂度 O(n) 、O(1),很有意思的一道题,可以多看看~
class Solution {public void nextPermutation(int[] nums) {// Case 1: 空数组 or 无元素if(nums == null || nums.length == 0) {return; }// 1. 先找最大索引 k,满足 nums[k] < nums[k + 1];不存在则翻转整个数组int firstIndex = -1;int len = nums.length;// 从后往前找for(int i = len - 2; i >= 0; i--) {if(nums[i] < nums[i + 1]) {firstIndex = i;break;}}// Case 2: 找不到的情况,直接翻转数组(即本就是最大排列)if(firstIndex == -1) {reverse(nums, 0, len - 1);return;}// 2. 然后找到第二个最大索引:满足 nums[sec] > nums[first]int secondIndex = -1;// 同样是从后往前找,找到的第一个肯定是最接近 nums[first]的值for(int i = len - 1; i >= 0; i--) {if(nums[i] > nums[firstIndex]) {secondIndex = i;break;}}// 3. 先交换 first 和 second(交换后,当前序列为nums[first : second]的最大序列)swap(nums, firstIndex, secondIndex);// 4. 然后对 nums[first + 1 :] 进行翻转(翻转后,当前序列为nums[first : second]的最小序列)reverse(nums, firstIndex + 1, len - 1);}// 翻转函数public void reverse(int[] nums, int i, int j) {while(i < j) {swap(nums, i++, j--);}}// 交换函数public void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}
二刷
- keywords:两个下标、交换、翻转
- firstIndex:第一个与后面的元素交换,能让排列变大的元素
- 交换:让排列变大
- 翻转:在大于初始排列的情况下,让排列变得最小。
class Solution {public void nextPermutation(int[] nums) {int firstIndex = nums.length;for(int i = nums.length - 2; i >= 0; i--) {if(nums[i] < nums[i + 1]) {firstIndex = i;break;}}if(firstIndex == nums.length) {reverse(nums, 0, nums.length - 1);return;}int secondIndex = nums.length;for(int i = nums.length - 1; i >= 0; i--) {if(nums[i] > nums[firstIndex]) {secondIndex = i;swap(nums, firstIndex, secondIndex);break;}}reverse(nums, firstIndex + 1, nums.length - 1);}void reverse(int[] nums, int left, int right) {while(left < right) {swap(nums, left++, right--);}}void swap(int[] nums, int left, int right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}
【LeetCode笔记】31. 下一个排列(Java、原地算法、偏数学)相关推荐
- 《LeetCode力扣练习》第31题 下一个排列 Java
<LeetCode力扣练习>第31题 下一个排列 Java 一.资源 题目: 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列. 例如,arr = [1,2,3] ,以下这些都可 ...
- Java实现 LeetCode 31下一个排列
31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...
- 【LeetCode】【HOT】31. 下一个排列
[LeetCode][HOT]31. 下一个排列 文章目录 [LeetCode][HOT]31. 下一个排列 package hot;import java.util.Arrays;public cl ...
- LeetCode每日一题--31. 下一个排列(数学)
题目:跳转至 31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原 ...
- 72.编辑距离105.前序中序遍历序列构造二叉树151.翻转字符串里的单词104.二叉树的最大深度76.最小覆盖子串110.平衡二叉树31.下一个排列
72.编辑距离 给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 .你可以对一个单词进行如下三种操作:插入一个字符,删除一个字符,替换一个字符. ...
- LeetCode 31. 下一个排列(线性扫描)
1. 题目 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...
- leetcode —— 31. 下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...
- Leetcode 31. 下一个排列 (每日一题 20210831)
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数).如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列).必须 原地 ...
- LeetCode 30串联所有单词的子串31下一个排列
标题 串联所有单词得字串 下一个排列 维护真的不易,如有帮助还请点赞关注,关注公众号bigsai回复进群即可加入打卡. 串联所有单词得字串 题目描述: 给定一个字符串 s 和一些长度相同的单词 wor ...
最新文章
- 计算机学科知识与教学能力初级中学,教师资格信息技术笔试(初级中学)难吗?...
- 《研磨设计模式》chap18 状态模式state(3)应用到场景
- 为什么我的理论和实践之间的差距相对较大
- boost::function模块实现分配器的测试程序
- Base64 算法原理,以及编码、解码【加密、解密】 介绍
- clientX和clientY属性需要注意的地方
- Shiro Shiro Web Support and EnvironmentLoaderListener
- mac 安装 SwitchHosts,链接都不好使了
- 小米与泰尔实验室联合发布《多模态技术白皮书》
- D92-02-ASEMI低压降快恢复二极管TO247封装
- java applet开发_Java Applet程序开发步骤
- 基础SQL第二课:约束
- D盘需要管理员权限解决办法
- Enzo高灵敏度检测——Arg8-Vasopressin ELISA kit
- 7z001怎么解压在安卓手机上面_手机怎么解压zip文件 安卓手机zip文件怎么打开?...
- openwrt 软件安装依赖冲突
- 计算机组装与维护教训,组装电脑:如果电脑出现异常一定要小心了,马虎可能会烧毁主板!...
- 银河麒麟 安装PL2303GC USB转串口驱动
- 乡镇卫生院计算机编制待遇怎么样,三甲医院VS乡镇卫生院事业编,选哪个?
- 关于EBGP用回环口起邻居遇到的问题
热门文章
- 调用图片文件夹中的任意图片随机显示_他来了,他来了,Mathpix拜拜了~~~文字、表格、公式图片识别神器V0.1测试版...
- 卧龙吟游戏服务器不显示,卧龙吟你必须知道的隐藏特性
- rust怎么拆除墙壁指令_人类跌落梦境:城堡怎么过 不少玩家卡在了第六关城堡地图这里...
- python编程环境安装包_Python环境安装与配置
- 友友球捕获率_神奇宝贝球内部秘密公开!大师球原来是这样达到100%捕获率的...
- tf.train.get_checkpoint_state
- linux系统下codeblocks控制台打印中文乱码
- simulink仿真学习(实现半波整流、方波输出) day1
- MFC中为菜单命令添加快捷键
- 大数据计算引擎:impala对比hive