↓快轉到主要內容
  1. LeetCode/

LeetCode 31: Next Permutation

·1 分鐘· ·
LeetCode Medium Array Two-Pointers
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-10-21

  • 提交紀錄:Accepted → Runtime Error ×2 → Wrong Answer → Accepted ×2 → Wrong Answer → Accepted ×2 → Wrong Answer → Accepted ×2

解題思路
#

Next Permutation 的固定步驟:

  1. 從右往左找第一個 nums[i] < nums[i + 1] 的位置 i。右邊 i + 1.. 是非遞增的,已經是最大的排列了。
  2. 找不到(整個非遞增)就整個反轉,變成最小的排列。
  3. 從右往左找第一個 nums[j] > nums[i],交換 i、j。
  4. 把 i + 1 之後反轉成遞增。

有重複值時,第 1、3 步的比較要用 >= / <= 跳過相等的。

我的嘗試
#

2022 年第一版的比較都用嚴格的 < / >,有重複值時停在錯的位置,例如 [1, 3, 1]:答案 [3, 1, 1],回傳 [1, 1, 3];另一版找交換對象時 j 往右走,超出範圍。2026 年重寫時一版反轉從 i + 1 開始,但我的 i 指的是下降位置的下一個,等於少反轉了一格,例如 [2, 3, 3]:答案 [3, 2, 3],回傳 [3, 3, 2]。

正確解法
#

class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        n = len(nums)
        i = n - 2
        while i >= 0 and nums[i] >= nums[i + 1]:
            i -= 1
        if i >= 0:
            j = n - 1
            while nums[j] <= nums[i]:
                j -= 1
            nums[i], nums[j] = nums[j], nums[i]
        nums[i + 1:] = reversed(nums[i + 1:])

複雜度
#

時間 O(n),空間 O(1)。

要特別避免的錯誤
#

  • 有重複值時比較要包含等於。
  • 反轉的是 i 之後的部分,從 i + 1 開始。

面試口說整理
#

我從右邊找第一個比右邊小的位置,跟右邊比它大的最小值交換,再把它後面反轉成遞增,就是下一個排列;找不到就整個反轉。時間 O(n)。

相關文章

LeetCode 11: Container With Most Water
·1 分鐘
LeetCode Medium Array Two-Pointers Greedy
LeetCode 11 解題筆記:左右指針從兩端開始,每次移動比較矮的那一邊;移動高的那邊只會讓寬度變小、高度不會變高
LeetCode 15: 3Sum
·2 分鐘
LeetCode Medium Array Two-Pointers Sorting
LeetCode 15 解題筆記:排序後固定第一個數,剩下用對撞指針找兩數和;三個位置都要跳過相同的值,才不會有重複的組合
LeetCode 16: 3Sum Closest
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting
LeetCode 16 解題筆記:排序後固定一個數,對撞指針找另外兩個;比較的是和跟 target 的距離 abs(sum - target)
LeetCode 18: 4Sum
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting
LeetCode 18 解題筆記:排序後兩層迴圈固定前兩個數,剩下用對撞指針;四個位置都要跳過相同的值
LeetCode 33: Search in Rotated Sorted Array
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 33 解題筆記:旋轉後 mid 的左右一定有一邊是排序好的,判斷目標在不在那一邊,在就往那邊找,不在就去另一邊
LeetCode 34: Find First and Last Position of Element in Sorted Array
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 34 解題筆記:做兩次 lower bound:第一個 >= target 的位置,以及第一個 >= target + 1 的位置減一