0
点赞
收藏
分享

微信扫一扫

Leetcode-40. 组合总和 II

王传学 2022-04-03 阅读 69

链接

40. 组合总和 II

题目

示例

说明

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

思路

如果解集可以包含重复的组合,那么这题很简单,按照正常的回溯的思路来即可。参考Leetcode-39. 组合总和

class Solution {
public:
    vector<vector<int>> res;
    vector<int> cur;
    void backtracking(vector<int>& candidates, int target, int cursum, int index){
        if(cursum==target) { res.push_back(cur); return; }
        if(cursum>target)  return; 
        for(int i=index;i<candidates.size(); i++)
        {
            cursum+=candidates[i];
            cur.push_back(candidates[i]);
            backtracking(candidates, target, cursum, i+1);
            cursum-=candidates[i];
            cur.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        backtracking(candidates, target, 0, 0);
        return res;
    }
};

但是在这题里,多了个条件,数组中有重复元素,且答案中不能出现重复数组,这就导致了像输入: candidates = [2,5,2,1,2], target = 5这种情况,我们遍历到起始下标为0的2,第二次选中下标为2的2,第三次选中1时,在后面遍历到起始下标index为2的2时,又会将起始下标为0的2这种情况再一次判断为正确,因此,我们可以先对数组进行排序,使得相同大小的数字挨在一块,当某个数字作为过起始下标时,后面遍历到相同的数字时排除这一情况,从而进行过滤。

C++ Code

class Solution {
public:
    vector<vector<int>> res;
    vector<int> cur;
    void backtracking(vector<int>& candidates, int target, int cursum, int index){
        if(cursum==target) { res.push_back(cur); return; }
        for(int i=index;i<candidates.size() && cursum + candidates[i] <= target; i++)
        {
            // 过滤之前已经作为过其实下表的元素
            if (i > index && candidates[i] == candidates[i - 1])  continue;
            cursum+=candidates[i];
            cur.push_back(candidates[i]);
            backtracking(candidates, target, cursum, i+1);
            cursum-=candidates[i];
            cur.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0);
        return res;
    }
};
举报

相关推荐

0 条评论