31. 下一个排列


题目


实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

解题思路


思路:迭代

首先先理解题意,题目中要求【将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在,则将数字重新排列称最小的排列(即升序排列)】

在这里,可能直接从文字上面来看,不太不能够理解是什么意思,那么结合例子来看,先看

1,2,3 → 1,3,2
1,1,5 → 1,5,1

在这里,你可以理解为,要将数字 123 变为下一个更大的数字,132。115 也同理。

而下面这个例子就是表示不存在更大的排列:

3,2,1 → 1,2,3

321 已经是最大的了,那么就将其排列为最小的排列(升序排列),得到结果 123。

其实从上面的例子中,多多少少也能够看出来,在这里其实是从后面开始找,当找到相邻升序的两个数字,在这里将它们进行交换,这样就能够得到更大的排列。

其实这里还有一部分的内容,在题目中是比较难看出来的,题目中【下一个】这个概念,其实要找到的是变化前后的排列,增加的幅度尽可能小。比如,下面的例子:

1,2,3,4,5 → 1,2,3,5,4
1,2,3,5,4 → 1,2,4,3,5

第一个示例,根据上面观察所得,即是将 4 和 5 进行替换,得到更大的排列,12354。

后面的示例中 12354,得到排列的结果 12435。在这里,交换的是 3 和 4,这里其实交换的数字是尽可能小的大数和前面的小数,所以并不是 3 和 5 进行交换,而交换后的所有数还需要重置升序。所得出的结果是 12435,而不是 12453。

这就是关于题意的简单分析,下面看如何实现算法:

  • 首先需要明确的是从后面往前查找第一个相邻升序的两个元素所在的位置(i,j),满足 A[i] < A[j]。而且,从位置 j 往后的元素是降序的。
  • 在 j 往后的元素中,同样是从后往前找,找到第一个满足 A[i] < A[k] 的元素,将其两者进行交换。
  • 前面说了, 从 j 往后一定是降序的,那么交换以后肯定也是降序的(因为找到 A[k] 是第一个比 A[i] 大的数字,由于是从后往前找,k所在位置左边的数字势必比当前 i 所在位置的数字大,而右边的数字也就比其小),这个时候,要将这部分降序,逆转为升序,这样才能保证排列前后尽可能小的增幅。
  • 考虑特殊的情况,也就是整个排列是降序,即是最大的的排列时,执行上面所说逆转为升序即可。

具体的代码实现如下。

代码实现


class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if len(nums) < 2:
return n = len(nums) # 从数组右往前进行遍历,查找相邻升序元素
i = n - 2
j = n - 1
while i > 0 and nums[i] >= nums[j]:
i -= 1
j -= 1
# 这里有一种情况,就是循环结束后,i 为 0 且索引 0 位置的数是最大的情况
# 那这里就表示排列就是最大的排列,将其逆转升序
if i == 0 and nums[i]==max(nums):
nums.reverse()
else:
# 当找到相邻的升序元素时
# 再次从后往前找到一个比 nums[i] 大但相比其他元素尽可能小的数
k = n - 1
while nums[i] >= nums[k]:
k -= 1
# 交换两个元素
nums[i], nums[k] = nums[k], nums[i] # 现在 j 到后面的元素是降序的,这里要将其升序
length = n - j + 1
for x in range(length // 2):
nums[j+x], nums[n-1-x] = nums[n-1-x], nums[j+x]

实现结果



以上就是关于《31. 下一个排列》问题的分析及具体实现算法的主要内容。


欢迎关注微信公众号《书所集录》

LeetCode 31. 下一个排列 | Python的更多相关文章

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

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

  2. LeetCode 31. 下一个排列(Next Permutation)

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

  3. leetcode 31下一个排列

    /** 验证一般情况(元素数目大于等于3)有几个情况分析:两个特殊情况: 6 5 4 3 2 1 完全反序,这种序列没有下一个排序,因此重新排序1 2 3 4 5 6 1 2 3 4 5 6 完全升序 ...

  4. LeetCode:下一个排列【31】

    LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...

  5. Leetcode题库——31.下一个排列

    @author: ZZQ @software: PyCharm @file: nextPermutation.py @time: 2018/11/12 15:32 要求: 实现获取下一个排列的函数,算 ...

  6. Leetcode题目31.下一个排列(中等)

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

  7. 【LeetCode】下一个排列【找规律】

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

  8. 代码题(45)— 下一个排列、第k个排列

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

  9. [LeetCode] 31. Next Permutation 下一个排列

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

随机推荐

  1. 常见的Web源码泄漏漏洞及其利用

    Web源码泄露的漏洞: git源码泄露 svn源码泄露 hg源码泄漏 网站备份压缩文件 WEB-INF/web.xml 泄露 DS_Store 文件泄露 SWP 文件泄露 CVS泄露 Bzr泄露 Gi ...

  2. web前端该怎么入门?web前端入门教程(非常详细)

    初学编程的小伙伴经常会遇到的问题,1.没资源 2.没人带 3.不知道从何开始 ,小编也是从新手期过来的,所以很能理解萌新的难处,现在整理一些以前自己学习的一些资料送给大家,希望对广大初学小伙伴有帮助! ...

  3. Scrapy中的crawlspider

    crawlspider 能自动的获取url并提交请求 命令:scrapy genspider -t crawl spidername 'example.cn' 所导入的模块 # -*- coding: ...

  4. asList和ArrayList不得不说的故事

    目录 简介 创建ArrayList UnsupportedOperationException asList 转换 总结 asList和ArrayList不得不说的故事 简介 提到集合类,ArrayL ...

  5. java 8 stream中的Spliterator简介

    目录 简介 tryAdvance trySplit estimateSize characteristics 举个例子 总结 java 8 stream中的Spliterator简介 简介 Split ...

  6. 如何迅速分析出系统CPU的瓶颈在哪里?

    内容出自极客时间专栏<Linux 性能优化实战> CPU 的性能指标那么多,CPU 性能分析工具一抓一大把,换成实际的工作场景,该观察什么指标.选择哪个性能工具呢? 不要担心,今天我就以多 ...

  7. 虚拟化VMware之虚拟机备份(1)

    之虚拟机备份() 模版:是一种开放,公用.安全的虚拟机压缩格式,通常使用的是扩展名为.ova可以在多个主流虚拟化平台下进行操作 是和 通过技术协作推出的基于磁盘的备份和恢复的新一代解决方案,可靠且易部 ...

  8. flex学习

            今天看视频学习的时候,发现css有一个 flex 的属性,非常的好用,为了让自己能够熟记,特意来分享一下flex的用法. 首先,采用Flex布局的元素,称为Flex容器(flex co ...

  9. 解决vue渲染时闪烁{{}}的问题

    原文转自: 点我 Vue页面加载时v-show设置的隐藏元素出现导致页面闪烁问题在写APP社区页面的时候在一些地方用了v-show,在刷新页面的时候就发现即便在逻辑判断为false某些元素不该显示时也 ...

  10. jmeter正则表达式提取多个数据/一组数据时,应该怎么做——debug sampler的使用

    背景:今天有个接口需要借助前面接口产生的一组ids数据,来作为入参使用,但是之前都是提取单个接口,所以到底怎么提取接口,遇到了很大的问题,按照多方查取资料都没有成功,最终在一个不相关帖子的最后一句话被 ...