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

LeetCode 77: Combinations

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

基本資料
#

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

  • 提交紀錄:Runtime Error ×3 → Accepted ×3

解題思路
#

組合不看順序,所以每次只從比上一個大的數開始選(Backtracking 模板):dfs(start, path),path 長度到 k 就記錄。剪枝:剩下的數不夠湊滿 k 個時直接停,i 只需要跑到 n - (k - len(path)) + 1。

我的嘗試
#

這題提交了 6 次:

  • 2022-10-26 的第一版呼叫 helper 時忘了 self.(NameError),helper 本身也有問題:在 for 迴圈裡直接 return 遞迴的結果,只會走第一條分支;range(0, now[-1]) 在 now 是空的時候 IndexError。
  • 一個月後重寫成「下一個數必須比上一個大」的回溯才 AC。

正確解法
#

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        def dfs(start, path):
            if len(path) == k:
                res.append(path[:])
                return
            for i in range(start, n - (k - len(path)) + 2):
                path.append(i)
                dfs(i + 1, path)
                path.pop()
        dfs(1, [])
        return res

複雜度
#

時間 O(k · C(n, k)),空間 O(k)(不算輸出)。

要特別避免的錯誤
#

  • 遞迴的 helper 要用 self. 呼叫,或寫成內部函式。
  • for 迴圈裡直接 return 遞迴的結果,只會走第一條分支。
  • 記錄答案時要複製 path[:]。

面試口說整理
#

組合不看順序,我用回溯,每次只從比上一個大的數開始選,選滿 k 個就記錄;剩下的數不夠湊滿 k 個時就剪掉。時間 O(k · C(n, k))。

相關文章

LeetCode 78: Subsets
·1 分鐘
LeetCode Medium Array Backtracking Bit-Manipulation
LeetCode 78 解題筆記:每個元素選或不選;迭代寫法是每加入一個數,就把現有的每個子集合複製一份並加上它
LeetCode 79: Word Search
·2 分鐘
LeetCode Medium Array String Backtracking Depth-First-Search
LeetCode 79 解題筆記:從每一格開始回溯,往四個方向比對下一個字元,走過的格子暫時標記,回溯時還原;先用字元次數剪枝
LeetCode 90: Subsets II
·1 分鐘
LeetCode Medium Array Backtracking Bit-Manipulation
LeetCode 90 解題筆記:先排序;遇到跟前一個相同的數,只延伸上一步新產生的那些子集合
LeetCode 47: Permutations II
·1 分鐘
LeetCode Medium Array Backtracking Sorting
LeetCode 47 解題筆記:先排序,同一層如果跟前一個值相同而且前一個還沒被用,就跳過
LeetCode 39: Combination Sum
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 39 解題筆記:同一個數可以重複選,所以遞迴時下一層從 i 開始(不是 i + 1),這樣也避免了順序不同的重複
LeetCode 40: Combination Sum II
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 40 解題筆記:每個數只能用一次而且有重複,排序後下一層從 i + 1 開始,同一層跳過跟前一個相同的值