LeetCode下一个排列
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
示例 4:
输入:nums = [1]
输出:[1]
思路:
这种题你第一次看的时候会一脸懵逼,等你做完,再过几个月又看,还是会一脸懵逼。因为对大多数人来说,本来就不是靠智力和“硬想”来做的,都是靠熟能生巧与套路总结而已。当然有些难题是可以硬想出来的,虽然靠自己做出来是挺爽的,不过那种思路多半毫无章法,代码也乱七八糟的,自己说不定都无法复现。
这也是我总结这些的目的,有些题就算我现在会写,如果不记住结论的话,再做还是不会。
这种“下一个排列、下一个较大值”,请直接记住套路:
首先,无法进行下一个排列的数组,自然就是从大到小排列的,即整个数组呈“一直下降”趋势。对于这种情况,我们根据题意把它升序排列即可。跟我们的算法无关。
而对于其他情况,必然会有某一处是有一个“上升”的情况。则操作方法如下:
1.从右往左,找到第一个“上坡”,“上坡”就是指相邻的两个数,左边小于右边。现在可以肯定的是,因为我们是从右向左找的,所以一旦找到“上坡”后,“上坡”的右边界往后肯定全都是“下坡”。
2.记录下“上坡”的左边界,从右往左,找比上坡左边界大的数,当然这样的数可能会有多个,我们只要找到第一个,就记录下这个值与位置,停止寻找。 这样做的意义是:在“上坡”左边界的右边,找到比左边界大的最小数。 说起来有点绕哈,但这样就可以保证,拿这个找到的数与左边界交换,就是最小交换。
3.把“上坡”左边界右边的部分从小到大排序。
代码:
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
#先处理特殊情况
s1 =sorted(nums[:],reverse=True) #将数组从大到小排列,和原数组比较
if s1==nums:#如果相同,说明没有下一个排列了,要进行升序排列
nums[:]=sorted(nums)#题目中要原地修改,要用切片
return #不要返回anything 在上面那行修改了即可,但是别忘了return来结束 否则错
#特殊情况处理完,开始真正的算法部分
lenth = len(nums)
lelf = lenth-2#left和right是从右往左查找的“窗口”
right = lelf+1
ll=0#ll和rr分别记录要交换的左右两个位置
rr=0#ll就是“上坡”的左边界,
#rr就是在“上坡”左边界的右边,找到的比左边界大的最小数
while(lelf>=0):#从右往左,找到第一个“上坡”,记录下左边的值
if nums[lelf]<nums[right]:#发现上坡!
ll = lelf
break#记录完毕,拜拜
lelf-=1
right-=1
for i in range(lenth-1,ll,-1):#从右向左寻找,记录下比他大的最小值
if nums[i]>nums[ll]:#发现第一个比上坡左边界大的值!
rr=i
break#记录完毕 拜拜
#二者交换
nums[ll],nums[rr]=nums[rr],nums[ll]
nums[:] = nums[:ll+1]+sorted(nums[ll+1:])#ll加1开始,往后的部分要排序
print(nums)
小结:
这里题目要求是要原地操作,用python的话,原地操作数组要用切片的形式。如果直接修改nums而不是nums[:],最终结果是不对的,所以要记住这个小技巧。
这个题的过程我说的太过详细了,看起来好像挺复杂——但实际上,就是“两次查找”+找到之后进行一次交换+对后半段排个序。大概就这么简单几步~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了