題目描述
解題思路
理解題意
本題首先最大的難點是理解題目的意思,題目意思是給定一個有幾個數字組成的數值,將這些數字重新排列,剛好得到比該數值大的新數值,如果沒有比題目給定的數值大的就返回題目給的數值。比如說:給定的數值爲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)