实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
down_index = None
# 第一步,从后往前,找到下降点
for i in range(n-2, -1, -1):
if nums[i+1] > nums[i]:
down_index = i
break
if down_index is not None:
# 第二步,从后往前,找到比下降点大的数,对换位置
for j in range(n-1, down_index, -1):
if nums[j] > nums[down_index]:
self.swap(nums, down_index, j)
break
# 第三部,下降点之后的数都是递减的,颠倒排序下降点之后的数
self.reverse(nums, down_index+1)
else:
# 如果没有下降点,说明数组是递减的,全部颠倒排列
self.reverse(nums, 0)
def swap(self, nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
# 这个是对数组进行翻转的标准方法
def reverse(self, nums, start_position):
i, j = start_position, len(nums)-1
while i < j:
self.swap(nums, i, j)
i += 1
j -= 1