Leetcode 40 组合总和 II

Leetcode组合总和II

  • 题目描述
    • 题解(回溯+剪枝)

题目描述

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为target的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。

来源:力扣(LeetCode)题目链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示 :

 - 1 <= candidates.length <= 100 
 - 1 <= candidates[i] <= 50 
 - 1 <= target <=30

题解(回溯+剪枝)

class Solution {
    vector<vector<int>> combination;
    vector<int> unit;
    int s;
public:
    void backtrace(vector<int>& candidates, int target, int p){
        if(0 >= target || p == s || target < candidates[p]){
            if(0 == target) combination.push_back(unit);
            else return;
        }
        else {
            for(int i=p; i<s; i++){
            // 本题关键1 ——题解去重
            // 理解:从backtrace退出后,即回到上一个i和p,此时i>p,如果candidates[i]==candidates[i-1], 说明会出现重复解
            // 举例: 1,2(1),2(2),2(3),3 5;
            // 1,2(1),2(2); 重复解1,2(1),2(3)被去除; 重复解1,2(2),2(3)被去除
                if(i>p && candidates[i]==candidates[i-1])
                    continue;
                unit.push_back(candidates[i]);
            // 本题关键2 ——每个数字选一次
                backtrace(candidates, target-candidates[i], i+1);
                unit.pop_back();
            }
        }
    } 
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        s = candidates.size();
        if(1 == s){
            if(target == candidates[0]) return vector<vector<int>>(1, candidates);
            else return vector<vector<int>>();
        }
        sort(candidates.begin(), candidates.end();
        backtrace(candidates, target, 0);
        return combination;
    }
};

Leetcode 40 组合总和 II_第1张图片

你可能感兴趣的:(leetcode,算法,数据结构)