题目:力扣
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例 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 <= nums.length <= 100
0 <= nums[i] <= 100
解题思路:
[1,2]的下一个排列是[2,1],[3,1,2]的下一个排列是[3,2,1],可以看出顺序变化是出现在数列某一个位置之后,比如[3,1,5,1,4]下一个是[3,1,5,4,1],可以看出前几位并没有发生变化,也就是说位置发生反转出现在升序的位置,特别的[2,4,3],下一个排列顺序是[3,2,4]可以看出,[4,3]保持这降序,2位置是第一个升序的位置,所以需要用2后面的某个数来替换2的位置(降序意味着这个数已经是当前元素可以表示的最大值了,如这里的43),那么替换2的一定是后面的某个比2刚刚大一点的数,且一旦替换了这个数后,后面的元素需要是升序来表示最小的数(如2,4,3用3替换2后得3,4,2,然而3,4,2大于3,2,4),所以从最后一位向前遍历,直至找到比2大的第一个元素与2换位置(2后面的一定是降序,因为2是第一个非降序元素),换位后对2原位置后的数再进行升序排列即可
注:尤其要注意相同元素的处理,在写大于小于的时候要考虑等于的情况,如[1,1,5]
代码:
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
r = n - 1
l = n - 2
# print(l, l+1)
# print(nums[l], nums[l+1])
while nums[l] >= nums[l + 1] and l >= 0:
l -= 1
if l != -1:
for i in range(n-1, l, -1):
if nums[i] <= nums[l]:
r -= 1
else:
t = nums[l]
nums[l] = nums[r]
nums[r] = t
break
t = nums[l+1: n]
t.sort()
nums[l+1: n] = t
return nums