# 40. Combination Sum II #### Difficulty: Medium link: https://leetcode.com/problems/combination-sum-ii/ ### 1. Backtracking #### $O(2^n)$ runtime, $O(2^n)$ space ### 走法1 這題是39.Combination Sum的follow up,不同點在於candidates內的數字有可能重複,並限制只能用一次。相比前一題的[答案](https://hackmd.io/@JHHsu/combination-sum),程式碼新增了第8~9行的條件判斷,避免拿到相同組合的情況。 範例測資一:[10,1,2,7,6,1,5] 排序後-> [1,1,2,5,6,7,10] 事先排序好candidates,如果有多個重複的數字,只拿start_index那一個,剩下的都跳過,如此就不會重複。 [1,1,6] [1,2,5] ##### python ```python= class Solution: def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: candidates.sort() result = [] def backtracking(path, start_index, value): for i in range(start_index, len(candidates)): cand = candidates[i] if i > start_index and cand == candidates[i-1]: continue if cand < value: backtracking(path + [cand], i + 1, value - cand) elif cand == value: result.append(path + [cand]) else: break backtracking([], 0, target) return result ``` ### 走法2 每次backtracking選擇要或不要拿idx的元素,同樣地,先拿idx那一個,如果idx數字有跟前面重複就跳過,之後再考慮不拿。 ##### python ```python= class Solution: def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: res = [] def backtracking(comb, idx, remain): if remain == 0: res.append(comb) return elif remain < 0 or idx > len(candidates)-1: return backtracking(comb+[candidates[idx]], idx+1, remain-candidates[idx]) while idx+1 < len(candidates) and candidates[idx+1] == candidates[idx]: idx += 1 backtracking(comb, idx+1, remain) candidates.sort() backtracking([], 0, target) return res ``` ###### tags: `leetcode`