目录
题目
- 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
题解:找规律
-
字典序:从左往右依次增大
-
思路:这里举一个实际的例子,比如[1,2,7,4,3]的下一个字典序为[1,3,2,4,7],思考如何转化而来,首先是2和3换了位置[1,3,7,4,2],然后再把3后面的部分翻转就得到了结果。现在问题转化为,如何完成上面两步。1.通过观察得2是反着遍历的第一个i+1大于i的;3是反着遍历第一个大于2的数,找到这两个位置就可以完成第一步的交换。2.接着是翻转操作,把i到len-1的元素全部翻转即可。
-
还有一种特殊情况:如[7,4,3,2,1]反着遍历没有找到i+1大于i的,此时由题干意思返回[1,2,3,4,7],只需翻转数组返回即可
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
n = len(nums)
if n <= 1: return
modify = -1
# 从后往前寻找非升序数组的第一个元素对应的下标modify
for i in range(n - 1, -1, -1):
if i == n - 1: continue
if nums[i] < nums[i + 1]:
modify = i
break
# 如果modify没变,则此时排列为最大,将数组逆序
if modify == -1:
nums[:] = nums[::-1]
# 否则
else:
target = -1
# 找到modify之后比modify大且最接近的元素的下标target
for i in range(n - 1, modify, -1):
if nums[i] > nums[modify]:
target = i
break
# 将modify和target位置的元素交换
nums[modify], nums[target] = nums[target], nums[modify]
# 将modify位置之后的元素倒序
i, j = modify + 1, n - 1
while i < j:
nums[i], nums[j] = nums[j], nums[i]
i, j = i + 1, j - 1
标签:arr,排列,nums,一个,31,modify,数组,字典
From: https://www.cnblogs.com/lushuang55/p/17996763