[Leetcode解題] Combination Sum - 遞迴/backtrace解
11 February 2022
medium
recursion
backtrace
題目
題目
給定一個不同整數的候選人陣列和目標整數目標,返回所有選定的數字的總和為目標的候選人的所有唯一組合的列表。您可以以任意順序返回組合。
解題思路
這道題可以使用回溯算法來解決,解題思路如下:
- 定義一個空列表 combination,用來存储每個組合。
- 從數組 candidates 中選擇一個數字加入 combination 列表,同時更新剩餘的 target。
- 如果剩餘的 target 等於 0,則將此 combination 加入結果列表;如果剩餘的 target 小於 0,則退出迴圈。
- 如果剩餘的 target 大於 0,則繼續從數組 candidates 中選擇數字加入 combination。
- 回到步驟 2,繼續遍歷整個數組。
- 如果 combination 不再繼續加入數字,則退出迴圈,並刪除最後一個數字,回到步驟 2 繼續遍歷整個數組。
- 重複步驟 2 到 6,直到所有數組都被遍歷完畢,得到所有組合。
實作
以下是一個使用回溯法的 Python 解決方案:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
def backtrack(start, target, combination, combinations):
if target == 0:
combinations.append(list(combination))
return
for i in range(start, len(candidates)):
if i > start and candidates[i] == candidates[i-1]:
continue
if target < candidates[i]:
break
combination.append(candidates[i])
backtrack(i, target-candidates[i], combination, combinations)
combination.pop()
candidates.sort()
combinations = []
backtrack(0, target, [], combinations)
return combinations
複雜度
在這個題目中,時間複雜度的計算方式是:$O(2^n)$,其中 $n$ 是數組的長度。因為每個數字都可以選或不選,所以總共有 $2^n$ 種可能的組合,因此需要遍歷整個數組。
但是,在本題的實現中,我們使用了剪枝技巧,可以大大縮短執行時間。因此,實際上的時間複雜度可能比 $O(2^n)$ 更低。