思路:
lexicographically, 可以理解成按照字典顺序排列,即如果把数组里的所有数字提取出来,变成一个数值,那么下一个排列组合就是用已有数值中已有数字排列组合,下一个比当前数值大的值。
[1,2,3,4,2,3,1] -> [1,2,3,4,3,1,2]
1234231<1234312
算法:
1. 从右往左遍历数组,找到第一个a[i],它的右边有比它大的数。
2. 找到它右边比它大的所有数中最小的一个,交换
3. 再对新a[i]右边的数进行升序排序,就可以保证新nums是原nums的下一个permutation.
注意:
步骤2找到它右边比它大的所有数中最小的一个,需要用到一些trick
遍历a[i]右边的所有数(从右往左遍历),此时他们是降序排序的(根据permutation的特性),所以第一个比a[i]大的数,一定是能取得的最小值。
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
for i in range(len(nums)-1,-1,-1):
#找到目标值,如果后一位大于前一位,则前一位是目标值
if nums[i]>nums[i-1]:
#找到目标值后面所有数中比目标值大的最小值
for j in range(len(nums)-1,-1,-1):
if nums[j]>nums[i-1]:
mini=nums[j]
nums[i-1],nums[j]=nums[j],nums[i-1]
break
break
#原目标值后面的数进行升序排序
nums[i:]=sorted(nums[i:])
另外,我不知道为什么中间加一个莫名其妙画蛇添足多次一举的找index的步骤,Runtime效率会比之前高,可能leetcode系统有毒吧。。。
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
for i in range(len(nums)-1,-1,-1):
#找到目标值,如果后一位大于前一位,则前一位是目标值
if nums[i]>nums[i-1]:
#找到目标值后面所有数中比目标值大的最小值
for j in range(len(nums)-1,-1,-1):
if nums[j]>nums[i-1]:
mini=nums[j]
break
nums[i:]=sorted(nums[i:])
#找到这个最小值的index
for j in range(len(nums)-1,-1,-1):
if nums[j]==mini:
index=j
break
#交换目标值和“最小值”
nums[i-1],nums[index]=nums[index],nums[i-1]
break
#原目标值后面的数进行升序排序
nums[i:]=sorted(nums[i:])