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

40. 组合总和 II

  • 题目要求
  • 题解
    • 加法回溯
    • 仿39题且参考上文解法
      • 细节总结

题目要求

给定一个数组 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++
  • 每次回溯结束后应判断下个元素是否与当前元素相同,避免重复。

你可能感兴趣的:(LeetCode刷题笔记 40. 组合总和 II)