LeetCode刷题笔记 40. 组合总和 II

题目要求

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

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

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-ii

题解

加法回溯

https://leetcode-cn.com/problems/combination-sum-ii/solution/zu-he-zong-he-hui-su-di-gui-8ms-98-by-er-zong/

class Solution {
public:
    void backtrack(vector<int>& candidates, int target, int sum, int begin){
        if(sum == target) {
            res.push_back(nums);
            return;
        } else
            while(begin<candidates.size() && sum+candidates[begin] <= target) {
                nums.push_back(candidates[begin]);
                backtrack(candidates, target, sum+candidates[begin++], begin);
            //回溯前去重
                while(begin<candidates.size() && candidates[begin] == candidates[begin-1]) ++begin;
                nums.pop_back();//回溯,进行下一位运算  
            }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        if(candidates.empty()){return res;}
        sort(candidates.begin(), candidates.end());
        backtrack(candidates, target, 0, 0);
        return res;
    }
private:
    vector<vector<int>> res;
    vector<int> nums;
};

仿39题且参考上文解法

可能是习惯减法了?

class Solution {
private:
    vector<int> candidates;
    vector<vector<int>> res;
    vector<int> path;
public:
    void DFS(int start,int target){
        if(target==0){
            res.push_back(path);
            return;
        }
        while(start<candidates.size()&&target-candidates[start]>=0){
            path.push_back(candidates[start]);
            //--------注意----------------------
            DFS(++start,target-candidates[start]);
            while(start<candidates.size()&&candidates[start]==candidates[start-1]) ++start;
            //---------------------------------
            path.pop_back();
        }
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        this->candidates=candidates;
        DFS(0,target);
        return res;        
    }    
    
};

细节总结

  • 元素可重复时采用for循环,该题不同于39题之处为使用while循环来避免同元素重复。
  • 使用while循环后应注意在使用递归DFSstart++
  • 每次回溯结束后应判断下个元素是否与当前元素相同,避免重复。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值