###### tags: `Leetcode` `medium` `array` `backtracking` `python` # 40. Combination Sum II ## [題目連結:]https://leetcode.com/problems/combination-sum-ii/ ## 題目: Given a collection of candidate numbers ```(candidates)``` and a target number (```target```), find all unique combinations in ```candidates``` where the candidate numbers sum to ```target```. Each number in ```candidates``` may only be used **once** in the combination. **Note:** The solution set must not contain duplicate combinations. **Example 1:** ``` Input: candidates = [10,1,2,7,6,1,5], target = 8 Output: [ [1,1,6], [1,2,5], [1,7], [2,6] ] ``` **Example 2:`` ``` Input: candidates = [2,5,2,1,2], target = 5 Output: [ [1,2,2], [5] ] ``` ## 解題想法: 兄弟題目:[39. Combination Sum](/W7B2e-02R7GECNxeVr0_vA) * 此題為: 給數組,求和為target的組合數 * **組合不能相同** * 每次組合,對於數組中任一位置的數**只能使用一次** * 起手式: * 先將數組排序,避免重複選擇 * 若干個數字相等,則需額外判斷重複問題: * ex: num=[1,1,2,5,6,7] , target=8 * 因為num[0]=1 與num[1]=1 兩個皆為1 * 當使用num[0]時 * 可以有組合[1, 1, 6], [1, 2, 5], [1, 7]了 * 所以換到nums[1]時 * 組合[1, 2, 5], [1, 7]會再重複 * 因此**要避免遞迴時使用與nums[i-1]相同值的數** ## Python: ``` python= class Solution(object): def combinationSum2(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ self.ans = [] candidates.sort() self.dfs(candidates,0,target,[]) return self.ans #pos 為當前check之candidate[pos] def dfs(self,candidates,pos,cur_target,path): if cur_target == 0: self.ans.append(path) for i in range(pos,len(candidates)): if candidates[i]>cur_target: break #避免遞迴時使用與nums[i-1]相同值的數 if i>pos and candidates[i]==candidates[i-1]: continue self.dfs(candidates,i+1,cur_target-candidates[i],path+[candidates[i]]) if __name__ == '__main__': result = Solution() #candidates = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] #target =27 candidates = [10,1,2,7,6,1,5] target = 8 ans = result.combinationSum2(candidates,target) print(ans) #Input: candidates = [10,1,2,7,6,1,5], target = 8 #Output: [[1,1,6],[1,2,5],[1,7],[2,6]] ```