题目描述
解题思路
理解题意
本题首先最大的难点是理解题目的意思,题目意思是给定一个有几个数字组成的数值,将这些数字重新排列,刚好得到比该数值大的新数值,如果没有比题目给定的数值大的就返回题目给的数值。比如说:给定的数值为123,比123大的数值有132、213、231、312、321,但题目要求的是刚好比123大一位的数值,就是132,而不是所有的更大数值,还要求空间复杂度为O(1)。
那么如何找到这个数呢,我们开始寻找规律。比如找出比上述的123刚好大一位的数值,为132,那么就是2和3交换位置。思考一下,难道所有的数交换位置就结束了吗?这是不一定的,因为交换后的数字变大了,但不是刚好大于原来的数值的。
再举一个例子,比如要求找到刚好比158476531大的数,那么从十位数3开始,看十位数的右边有没有大于3,没有就再看百位数5右边是否有大于5的,依次类推,可以看到3,5,6,7的右边都没有大于他们本身的数。那么就来到4,4的右边有很多大于4的,选择刚好大于4的5进行交换得到158576431,这个数大于158476531,但不是刚好大于,则不符合要求,这是还需要将5右边的数按从小到大排列,得到158513467,符合要求结束。
解题思路
将给定的数字组成的序列,从右到左找到第一个不再递增的位置,将该位置的数字与右边刚好大于它的数字交换,再将该位置右边的数字降序排列,得到最终结果
python代码
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i = len(nums)-2
# 找到第一个不再递增的位置
while i >= 0 and nums[i+1]<=nums[i]:
i -= 1
# 如果到了最左边,就直接倒置输出
if i >= 0:
# 刚好找到大于num[i]的位置
j = len(nums)-1
while j >= 0 and nums[j]<=nums[i]:
j -= 1
# 交换
self.swap(nums, i, j)
# 利用倒置进行排序
self.reverse_ll(nums, i + 1)
def swap(self,nums, i, j):
temp = nums[j]
nums[j] = nums[i]
nums[i] = temp
def reverse_ll(self,nums,start):
i = start
j = len(nums) - 1
while i < j:
self.swap(nums, i, j)
i += 1
j -= 1
s = Solution()
res = s.nextPermutation([1,2,3])
print(res)