給定一個無重複正整數數組 candidates
和一個目標值 target
,找出所有可以使數字和為 target
的組合。
數組中的數字可以無限制重複選取,並且所有的組合需要是唯一的。
範例 1
輸入: candidates = [2,3,6,7], target = 7
輸出: [[2,2,3],[7]]
解釋:
2 + 2 + 3 = 7
7 = 7
範例 2
輸入: candidates = [2,3,5], target = 8
輸出: [[2,2,2,2],[2,3,3],[3,5]]
範例 3
輸入: candidates = [2], target = 1
輸出: []
target
)均為正整數。這是一個經典的「組合問題」,解題的核心是利用回溯法(Backtracking)。
target
,停止探索(剪枝)。target
,將當前組合加入結果集。class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def backtrack(start, target, path):
if target == 0:
result.append(list(path)) # 找到一個組合
return
if target < 0:
return # 剪枝
for i in range(start, len(candidates)):
path.append(candidates[i]) # 選擇當前元素
backtrack(i, target - candidates[i], path) # 繼續探索
path.pop() # 撤銷選擇
result = []
candidates.sort() # 排序有助於剪枝
backtrack(0, target, [])
return result
t
是目標值 target
,因為每個數字可能被多次選取並組成不同的組合。target
。dp[i]
為目標和為 i
的所有組合。num
和目標值 j
,若 j >= num
,則將 dp[j - num]
中的組合加上 num
,形成新的組合,並存入 dp[j]
。class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
dp = [[] for _ in range(target + 1)]
dp[0] = [[]] # 和為 0 時的組合為空組合
for num in candidates:
for j in range(num, target + 1):
for comb in dp[j - num]:
dp[j].append(comb + [num])
return dp[target]
n
是候選數組的大小,target
是目標值。candidates
較小時,使用回溯法;當目標值較大時,考慮動態規劃。