---
# System prepended metadata

title: 40. Combination Sum II
tags: [Leetcode, medium, python, array, backtracking]

---

###### 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]]
```