Combination Sum,Combination Sum II,Combination Sum III

时间:2022-10-13 19:54:23

39. Combination Sum

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

For example, given candidate set 2,3,6,7 and target 7
A solution set is: 
[7] 
[2, 2, 3] 

题目要求求出和为target的所有不重复组合,数据源中的数据可以重复使用

深度优先+回溯,可剪枝

class Solution {
private:
    void dsf(vector<int>& datas,int start,vector<vector<int>>& res,vector<int>& oneRes,int target,int curSum)
    {
        for(int i=start;i<datas.size();++i){
            
            if(i>start && datas[i]==datas[i-1]){
                continue;
            }
            
            if(curSum + datas[i] > target){//break跳出循环,剪枝
                break;
            }
            
            if(curSum + datas[i] == target){//break跳出循环,剪枝
                oneRes.push_back(datas[i]);
                res.push_back(oneRes); 
                oneRes.pop_back();
                break;
            }

            oneRes.push_back(datas[i]);            
            curSum += datas[i];
            
            dsf(datas,i,target,res,oneRes,curSum);
            
            curSum -= datas[i];
            oneRes.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> res;
        vector<int> oneRes;
        dsf(candidates,0,target,res,oneRes,0);
        return res;
    }
};

40. Combination Sum II

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

For example, given candidate set 10,1,2,7,6,1,5 and target 8
A solution set is: 
[1, 7] 
[1, 2, 5] 
[2, 6] 
[1, 1, 6]

这题跟上面那题没有什么区别 

class Solution {
private:
    void dsf(vector<int>& datas,int start,vector<vector<int>>&res,vector<int>& oneRes,int target,int curSum){
        for(int i=start;i<datas.size();++i){
            
            if(i>start && datas[i]==datas[i-1]){
                continue;
            }
            
            int tmpSum = curSum + datas[i];
            
            if(tmpSum > target){
                break;
            }
            
            if(tmpSum == target){
                oneRes.push_back(datas[i]);
                res.push_back(oneRes);
                oneRes.pop_back();
                break;
            }
            
            oneRes.push_back(datas[i]);
    
            dsf(datas,i+1,target,res,oneRes,tmpSum);
            
            oneRes.pop_back();
            
        }
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> res;
        vector<int> oneRes;
        dsf(candidates,0,target,res,oneRes,0);
        return res;
    }
};

216. Combination Sum III

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Ensure that numbers within the set are sorted in ascending order.

Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]

Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

这题可以使用与上面两题一样的方法

class Solution {
private:
    void dfs(int start,vector<vector<int>>&res,vector<int>& oneRes,int k,int target,int curSum)
    {
        for(int i=start;i<=9;++i){
            
            if(curSum + i > target){
                break;
            }
            
            if(curSum + i == target && k-1==0){
                oneRes.push_back(i);
                res.push_back(oneRes);
                oneRes.pop_back();
                break;
            }
            
            if(k==0){
                break;
            }
            
            oneRes.push_back(i);
            curSum += i;
            
            dfs(i+1,res,oneRes,k-1,target,curSum);
            
            curSum -= i;
            oneRes.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<vector<int>> res;
        vector<int> oneRes;
        dfs(1,res,oneRes,k,n,0);
        return res;
    }
};

当然,这题还可以使用ksum的方法,先算法2sum,然后3sum...ksum