【Leetcode 31】下一個排列

題目描述

在這裏插入圖片描述

解題思路

理解題意

本題首先最大的難點是理解題目的意思,題目意思是給定一個有幾個數字組成的數值,將這些數字重新排列,剛好得到比該數值大的新數值,如果沒有比題目給定的數值大的就返回題目給的數值。比如說:給定的數值爲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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章