1. 程式人生 > >LeetCode31-下一個排列

LeetCode31-下一個排列

這兩天屁事兒特別多,就一直沒有更新,心裡其實慌慌的,一是感覺自己太懶了,二是覺得有些對不起大家,所以今天閒下來了趕緊更新一波!


31-下一個排列

實現獲取下一個排列的函式,演算法需要將給定數字序列重新排列成字典序中下一個更大的排列。

如果不存在下一個更大的排列,則將數字重新排列成最小的排列(即升序排列)。

必須原地修改,只允許使用額外常數空間。

以下是一些例子,輸入位於左側列,其相應輸出位於右側列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

說到這一題,我踩得坑那著實是不少,之前沒有把題目意思仔細研讀,就匆匆動筆了,導致後面bug十多次,而氣的是自己一直以為自己沒有做錯。

我第一次的想法是這樣的:採用python中itertools.permutations()排列函式首先求得給定序列當中的數不同的排列情況,然後依次遍歷,只要發現有比原序列大,立即返回該系列。我寫的程式碼很簡單,當時覺得自己太聰明瞭,只有天才如自己才能想到這麼簡單的辦法,誰知道bug十多次,當時已經崩潰了。

程式碼如下:

from itertools import permutations


class Solution:
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        if len(nums) == 0 or len(nums) == 1:
            return
        # 求得給定序列當中的數不同的排列情況
        nums_permutation = list(permutations(nums))
        # 依次遍歷nums_permutation求得第一個比nums大的序列返回
        for index in nums_permutation:
            index = list(index)
            if index > nums:
                nums[:] = index
                print("nums", nums)
                return
        nums.sort()
        print(nums)


if __name__ == "__main__":
    nums = [1, 2, 3]
    Solution().nextPermutation(nums)

大家感興趣的也可以run run試試,很有意思的,相信我!

當時氣得沒辦法,找了網上的大神,看到他們的解法才知道我的問題出在哪兒,核心點就是我沒有考慮到將給定數字序列重新排列成字典序中下一個更大的排列。這個順序才是最關鍵的,而我之前並沒有考慮,問題找到了,那做起來就很快了。

思路:

  1. 首先找到nums陣列中從右往左第一個左邊值比右邊值小的下標值,如果沒找到(即該序列為規則的逆序序列)
  2. 再將該下標值對應的數與後面最後一個比它大的數交換
  3. 交換完之後,將1中找到的下標值後面的所有數升序排列

程式碼如下:

class Solution:
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        # 首先找到nums陣列中從右往左第一個左邊值比右邊值小的下標值
        if len(nums) == 0 or len(nums) == 1:
            return
        index = len(nums) - 2
        while index >= 0 and nums[index] >= nums[index+1]:
            index -= 1
        if index >= 0:
            self.swap(nums, index)
            # 然後將index後面的值用sort()方法從小到大排列
            nums_copy = []
            nums_copy.extend(nums[index+1:])
            nums_copy.sort()
            nums[index+1:] = nums_copy
            print("nums", nums)
            return
        nums.sort()
        print("nums", nums)

    # 將找到的index下標值與相鄰最大的值交換
    def swap(self, nums, index):
        for next_index in range(len(nums)-1, index, -1):
            if nums[next_index] > nums[index]:
                temp = nums[index]
                nums[index] = nums[next_index]
                nums[next_index] = temp
                return

執行效率在70%以上。