此题比较难考虑
我们这样想:
先考虑最难搞的情况 也就是题目中所说的“不存在更大的排列”
此时,输入是全递减序列
这时,我们只需要把原数组倒序即可
接下来我们考虑一般的情况,也就是存在更大的排列
此时,我们只需要把比输入序列组成的N位数中大于原顺序的N位数最小的数即可
如 比1 3 2 更大的 数里 最小的 是 2 1 3
为了实现这个功能
我们观察序列的末尾部分,如果末尾是升序
例如 2 1 3 4
我们只需要把最后两个交换即可
如果末尾是降序,因为我们在一开始已经排除了全降序的可能
因此,序列在最后的部分 一定是 先递增 再递减
如2 1 4 3
我们观察序列的后半部分,即递减前一个数字,即上面的 1 4 3
此时,我们称4为峰顶a,称1为b,我们需要找到峰顶及后面(含峰顶)比b大的最小的数c
然后将b和c两个位置的数字交换,最后再将b之后的序列倒序
即可
class Solution:
def nextPermutation(self, nums):
"""
Do not return anything, modify nums in-place instead.
"""
length = len(nums)
done = False
for i in range(1,length):
if nums[i-1] < nums[i]:#后一个小于前一个
break
elif nums[i] <= nums[i-1] and i == length - 1:
nums[:] = nums[::-1]
done = True#全部是递减,此时是最后一个全排列,直接改为第一个即可
if done == False and length > 1:
if nums[-1] > nums[-2]:#若尾部是升序,我们将尾部的倒数两个交换即可
nums[length - 1],nums[length - 2] = nums[length - 2],nums[length - 1]
#nums[-1],nums[-2] = nums[-2],nums[-1]
else:
#先找到尾部降序的起点a,然后找到这个起点之前的那个低谷点b
#然后找尾部降序中最小的比b大的数字c
index = length - 1
while nums[index] <= nums[index - 1]:
index -= 1
#此时nums[index] > nums[index - 1]
b = nums[index - 1]
a = nums[index]#峰顶
#先看看最后一个是不是c
if nums[-1] > b:
nums[-1],nums[index - 1] = nums[index - 1],nums[-1]
else:
for i in range(index,length - 1):
if nums[i] > b and nums[i+1] <= b:
nums[i],nums[index - 1] = nums[index - 1],nums[i]
nums[index:] = nums[index:][::-1]