# 组合总和 II
<p>给定一个数组&nbsp;<code>candidates</code>&nbsp;和一个目标数&nbsp;<code>target</code>&nbsp;，找出&nbsp;<code>candidates</code>&nbsp;中所有可以使数字和为&nbsp;<code>target</code>&nbsp;的组合。
</p>
<p><code>candidates</code>&nbsp;中的每个数字在每个组合中只能使用一次。</p>
<p><strong>说明：</strong></p>
<ul>
    <li>所有数字（包括目标数）都是正整数。</li>
    <li>解集不能包含重复的组合。&nbsp;</li>
</ul>
<p><strong>示例&nbsp;1:</strong></p>
<pre><strong>输入:</strong> candidates =&nbsp;[10,1,2,7,6,1,5], target =&nbsp;8,<strong><br />所求解集为:</strong>[[1, 7],[1, 2, 5],[2, 6],[1, 1, 6]]</pre>
<p><strong>示例&nbsp;2:</strong></p>
<pre><strong>输入:</strong> candidates =&nbsp;[2,5,2,1,2], target =&nbsp;5,<strong><br />所求解集为:</strong>[[1,2,2],[5]]</pre>
<p>以下错误的选项是？</p>
## aop
### before
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
```cpp
int main()
{
    Solution sol;
    vector<vector<int>> res;
    vector<int> candidates = {10, 1, 2, 7, 6, 1, 5};
    int target = 8;

    res = sol.combinationSum2(candidates, target);

    for (auto i : res)
    {
        for (auto j : i)
            cout << j << " ";
        cout << endl;
    }
    return 0;
}
```

## 答案
```cpp
class Solution
{
public:
    vector<vector<int>> combinationSum2(vector<int> &candidates, int target)
    {
        vector<int> temp;
        vector<vector<int>> result;
        sort(candidates.begin(), candidates.end());
        getans(candidates, target, 0, result, temp);
        return result;
    }
    void getans(vector<int> candidates, int target, int start, vector<vector<int>> &result, vector<int> temp)
    {
        if (target == 0)
        {
            result.push_back(temp);
        }
        else if (target > 0)
        {
            int k = candidates.size() - 1;
            while (target < candidates[k])
                k--;
            for (int i = start; i <= k; i++)
            {
                if (i != start && candidates[i] == candidates[i - 1])
                    continue;
                temp.push_back(candidates[i]);
                getans(candidates, target, i, result, temp);
                temp.pop_back();
            }
        }
    }
};
```
## 选项

### A
```cpp
class Solution
{
public:
    vector<vector<int>> combinationSum2(vector<int> &candidates, int target)
    {
        vector<vector<int>> res;
        sort(candidates.begin(), candidates.end());
        dfs(candidates, 0, target, res);
        return res;
    }

private:
    vector<int> stack;
    void dfs(vector<int> &candidates, int start, int target, vector<vector<int>> &res)
    {
        if (target < 0)
        {
            return;
        }
        else if (target == 0)
        {
            res.push_back(stack);
        }
        else
        {
            int last = INT_MIN;
            for (int i = start; i < candidates.size(); i++)
            {
                if (last != candidates[i])
                {
                    stack.push_back(candidates[i]);
                    dfs(candidates, i + 1, target - candidates[i], res);
                    stack.pop_back();
                }
                last = candidates[i];
            }
        }
    }
};
```

### B
```cpp
class Solution
{
public:
    vector<vector<int>> combinationSum2(vector<int> &candidates, int target)
    {
        vector<vector<int>> res;
        vector<int> temp;
        backtrace(candidates, temp, 0, target);
        res.assign(m_set.begin(), m_set.end());
        return res;
    }

    void backtrace(vector<int> &candidates,
                   vector<int> &temp,
                   int index,
                   int target)
    {

        if (target == 0)
        {
            sort(temp.begin(), temp.end());
            /* 去重 */
            m_set.insert(temp);
            return;
        }

        /* 设定边界*/
        if (index == candidates.size())
        {
            return;
        }

        if (target >= candidates[index])
        {
            vector<int> tmp(temp);
            tmp.push_back(candidates[index]);
            backtrace(candidates, tmp, index + 1, target - candidates[index]);
        }
        backtrace(candidates, temp, index + 1, target);
    }

private:
    set<vector<int>> m_set;
};
```

### C
```cpp
class Solution
{
public:
    void dfs(vector<vector<int>> &ans, vector<int> &candidates, vector<int> &tmp, int target, int start)
    {
        if (target == 0)
        {
            ans.push_back(tmp);
            return;
        }
        else if (target < 0)
        {
            return;
        }
        else
        {
            for (int i = start; i < candidates.size(); i++)
            {
                tmp.push_back(candidates[i]);
                dfs(ans, candidates, tmp, target - candidates[i], i + 1);
                tmp.pop_back();
                while (i + 1 < candidates.size() && candidates[i] == candidates[i + 1])
                    i++;
            }
        }
    }

    vector<vector<int>> combinationSum2(vector<int> &candidates, int target)
    {
        vector<vector<int>> ans;
        vector<int> tmp;

        if (candidates.empty())
            return ans;

        sort(candidates.begin(), candidates.end());
        dfs(ans, candidates, tmp, target, 0);
        return ans;
    }
};
```
