文章目录

  • 题目描述
  • 思路 && 代码
    • 二刷

打卡第八天~

题目描述

  • 需要花点时间思考的一道题,这篇题解写得很好。

思路 && 代码

  • 主要分为这三个步骤:

    1. 从后往前找到满足 nums[first] < nums[first + 1] 的索引 first
    2. 从后往前找到满足 nums[second] > nums[first] 的索引 second
    3. 交换 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 大佬的例子
    1. 对于 nums = [1, 2, 7, 4, 3, 1]
    2. 找到 nums[first] = nums[1] = 2
    3. 找到 nums[second] = nums[4] = 3
    4. 交换 nums = [1, 3, 7, 4, 2, 1](可以看到 7 4 2 1 是刚好降序排列的)
    5. 翻转 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、原地算法、偏数学)相关推荐

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

    <LeetCode力扣练习>第31题 下一个排列 Java 一.资源 题目: 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列. 例如,arr = [1,2,3] ,以下这些都可 ...

  2. Java实现 LeetCode 31下一个排列

    31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...

  3. 【LeetCode】【HOT】31. 下一个排列

    [LeetCode][HOT]31. 下一个排列 文章目录 [LeetCode][HOT]31. 下一个排列 package hot;import java.util.Arrays;public cl ...

  4. LeetCode每日一题--31. 下一个排列(数学)

    题目:跳转至 31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原 ...

  5. 72.编辑距离105.前序中序遍历序列构造二叉树151.翻转字符串里的单词104.二叉树的最大深度76.最小覆盖子串110.平衡二叉树31.下一个排列

    72.编辑距离 给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 .你可以对一个单词进行如下三种操作:插入一个字符,删除一个字符,替换一个字符. ...

  6. LeetCode 31. 下一个排列(线性扫描)

    1. 题目 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...

  7. leetcode —— 31. 下一个排列

    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...

  8. Leetcode 31. 下一个排列 (每日一题 20210831)

    实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数).如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列).必须 原地 ...

  9. LeetCode 30串联所有单词的子串31下一个排列

    标题 串联所有单词得字串 下一个排列 维护真的不易,如有帮助还请点赞关注,关注公众号bigsai回复进群即可加入打卡. 串联所有单词得字串 题目描述: 给定一个字符串 s 和一些长度相同的单词 wor ...

最新文章

  1. 计算机学科知识与教学能力初级中学,教师资格信息技术笔试(初级中学)难吗?...
  2. 《研磨设计模式》chap18 状态模式state(3)应用到场景
  3. 为什么我的理论和实践之间的差距相对较大
  4. boost::function模块实现分配器的测试程序
  5. Base64 算法原理,以及编码、解码【加密、解密】 介绍
  6. clientX和clientY属性需要注意的地方
  7. Shiro Shiro Web Support and EnvironmentLoaderListener
  8. mac 安装 SwitchHosts,链接都不好使了
  9. 小米与泰尔实验室联合发布《多模态技术白皮书》
  10. D92-02-ASEMI低压降快恢复二极管TO247封装
  11. java applet开发_Java Applet程序开发步骤
  12. 基础SQL第二课:约束
  13. D盘需要管理员权限解决办法
  14. Enzo高灵敏度检测——Arg8-Vasopressin ELISA kit
  15. 7z001怎么解压在安卓手机上面_手机怎么解压zip文件 安卓手机zip文件怎么打开?...
  16. openwrt 软件安装依赖冲突
  17. 计算机组装与维护教训,组装电脑:如果电脑出现异常一定要小心了,马虎可能会烧毁主板!...
  18. 银河麒麟 安装PL2303GC USB转串口驱动
  19. 乡镇卫生院计算机编制待遇怎么样,三甲医院VS乡镇卫生院事业编,选哪个?
  20. 关于EBGP用回环口起邻居遇到的问题

热门文章

  1. 调用图片文件夹中的任意图片随机显示_他来了,他来了,Mathpix拜拜了~~~文字、表格、公式图片识别神器V0.1测试版...
  2. 卧龙吟游戏服务器不显示,卧龙吟你必须知道的隐藏特性
  3. rust怎么拆除墙壁指令_人类跌落梦境:城堡怎么过 不少玩家卡在了第六关城堡地图这里...
  4. python编程环境安装包_Python环境安装与配置
  5. 友友球捕获率_神奇宝贝球内部秘密公开!大师球原来是这样达到100%捕获率的...
  6. tf.train.get_checkpoint_state
  7. linux系统下codeblocks控制台打印中文乱码
  8. simulink仿真学习(实现半波整流、方波输出) day1
  9. MFC中为菜单命令添加快捷键
  10. 大数据计算引擎:impala对比hive