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

LeetCode 39: Combination Sum

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

基本資料
#

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

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

解題思路
#

每個數可以用無限次,但答案不看順序。dfs(start, remain, path) 的下一層從 i 開始(Backtracking 模板):可以再選自己,但不會回頭選前面的數,所以 [2, 2, 3] 和 [3, 2, 2] 只會出現一次。排序後 candidates[i] > remain 就可以 break。

我的嘗試
#

  • 2022-10-21 第一版每一層都從頭選,同一組數字的不同順序都被記錄了:[2, 3]、target = 9 回傳了四次 [2, 2, 2, 3]。
  • 2022-10-30 重寫時一版把 0 也放進了組合([[0, 5]]),另一版遞迴的條件寫錯,[2]、target = 8 回傳空的。
  • 2022-11-23 改成「下一個數不能比上一個小」才 AC。

正確解法
#

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        res = []
        def dfs(start, remain, path):
            if remain == 0:
                res.append(path[:])
                return
            for i in range(start, len(candidates)):
                if candidates[i] > remain:
                    break
                path.append(candidates[i])
                dfs(i, remain - candidates[i], path)
                path.pop()
        dfs(0, target, [])
        return res

複雜度
#

時間指數級(取決於 target 和最小的數),空間 O(target / min)。

要特別避免的錯誤
#

  • 下一層從 i 開始:從 0 開始會產生順序不同的重複答案,從 i + 1 開始就不能重複使用。
  • remain == 0 時記錄,不要記錄空的組合。

面試口說整理
#

每個數可以重複選,但答案不看順序,所以我回溯時下一層從同一個 index 開始,可以再選自己但不會回頭選前面的數;排序後超過剩下的目標就停止。

相關文章

LeetCode 40: Combination Sum II
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 40 解題筆記:每個數只能用一次而且有重複,排序後下一層從 i + 1 開始,同一層跳過跟前一個相同的值
LeetCode 46: Permutations
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 46 解題筆記:每一層從還沒用過的數裡選一個,用 used 陣列標記,path 滿了就記錄
LeetCode 31: Next Permutation
·1 分鐘
LeetCode Medium Array Two-Pointers
LeetCode 31 解題筆記:從右邊找第一個下降的位置 i,跟右邊比它大的最小值交換,再把 i 之後反轉;比較時要包含等於
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 的位置減一
LeetCode 36: Valid Sudoku
·1 分鐘
LeetCode Medium Array Hash-Table Matrix
LeetCode 36 解題筆記:每個數字在列、欄、3 × 3 宮格各只能出現一次;用 (數字, 列)、(數字, 欄)、(數字, 宮格) 當 key 放進同一個集合