39 / 40 Combination Sum(I / II)

Total Accepted: 83289  Total Submissions: 274461  Difficulty: Medium

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 (a1a2, … , 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] 

Subscribe to see which companies asked this question

Hide Tags
  Array Backtracking
Hide Similar Problems
  (M) Letter Combinations of a Phone Number (M) Combination Sum II (M) Combinations (M) Combination Sum III (M) Factor Combinations

分析:

本题和前面的三篇博客题目意思基本一样的,只是这里的组合可以是相同的数字

本题联动:

<LeetCode OJ> 216. Combination Sum III

<LeetCode OJ> 77. Combinations

<LeetCode OJ> 78 / 90 Subsets (I / II)

class Solution {
public:
    void dfs(vector<int>& nums, vector<int> &subres,int sum, int start, int target)//使用引用,有利于防止内存大爆炸    
    {    
        if(sum == target)//已经获得答案,并且回溯    
        {    
            result.push_back(subres);  
            return;  
        }
        
        for (int i = start; i < nsize; i++)    
        {    
            if(nums[i] > target  || (sum+nums[i]) > target)//这条路不符要求,回溯
                return;
            subres.push_back(nums[i]);
            dfs(nums, subres,sum+nums[i],i,target);//执行一个深度上的组合,并计算和。
            subres.pop_back();//每当执行完一个深度上的组合就弹掉末尾元素
        }  
    }  
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        nsize=candidates.size();  
        if ( nsize == 0)     
            return result;   
        sort(candidates.begin(),candidates.end()); //一,先排序     
        vector<int> subres;    
        dfs(candidates, subres,0,0, target);    
        return result;    
    }  
      
private:  
    vector<vector<int > > result;  
    int nsize;  
};




以前的错误答案,多么痛的领悟:

class Solution {
public:
    void dfs(vector<int>& nums, vector<int> &subres,int sum, int start, int target)//使用引用,有利于防止内存大爆炸    
    {    
        if(sum == target)//已经获得答案,并且回溯    
        {    
            result.push_back(subres);  
            return;  
        }
        if(sum > target)//这条路不符合要求,回溯
        {   
            return;
        }
            
        for (int i = start; i < nsize; i++)    
        {    
            sum+=nums[i];//错误!!!
            subres.push_back(nums[i]);
            dfs(nums, subres,sum,i,target);
            subres.pop_back();
        }  
    }  
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        nsize=candidates.size();  
        if ( nsize == 0)     
            return result;   
        sort(candidates.begin(),candidates.end()); //一,先排序     
        vector<int> subres;    
        dfs(candidates, subres,0,0, target);    
        return result;    
    }  
      
private:  
    vector<vector<int > > result;  
    int nsize;  
};





Total Accepted: 62935  Total Submissions: 231780  Difficulty: Medium

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 (a1a2, … , 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] 

Subscribe to see which companies asked this question

Hide Tags
  Array Backtracking
Hide Similar Problems
  (M) Combination Sum

分析:

和上面的题目没撒区别,不再分析!

耗时16ms

class Solution {
public:
    void dfs(vector<int>& nums, vector<int> &subres,int sum, int start, int target)//使用引用,有利于防止内存大爆炸      
    {      
        if(sum == target)//已经获得答案,并且回溯      
        {      
            if(!isSameVec(subres))
                result.push_back(subres);    
            return;    
        }  
        for (int i = start; i < nsize; i++)      
        {      
            if(nums[i]>target || (sum+nums[i]) > target)//回溯
                return;
            subres.push_back(nums[i]);  
            dfs(nums, subres,sum+nums[i],i+1,target);//执行一个深度上的组合,并计算和。计算和时一定要这样计算(可以保留本层的sum)  
            subres.pop_back();//每当执行完一个深度上的组合就弹掉末尾元素  
        }    
    }   
    bool isSameVec(vector<int> &sub)
    {
        for(int i=0;i<result.size();i++)
        {
            if(result[i]==sub)
                return true;
        }
        return false;
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        nsize=candidates.size();    
        if ( nsize == 0)       
            return result;     
        sort(candidates.begin(),candidates.end()); //一,先排序       
        vector<int> subres;      
        dfs(candidates, subres,0,0, target);      
        return result;      
    }
    
private:    
    vector<vector<int > > result;    
    int nsize; 
};




学习别人的优秀算法:8ms

class Solution {
public:
    vector<vector<int> > combinationSum2(vector<int> &num, int target) 
    {
        sort(num.begin(),num.end());
        vector<int> subresult;
        dfs( 0, target, subresult, num);
        return result;
    }
    void dfs(const int order, const int target, vector<int>& subresult, const vector<int>& num)
    {
        if(target==0)
        {
            result.push_back(subresult);
            return;
        }
        
        for(int i = order;i<num.size();i++) // iterative component
        {
            if(num[i]>target) 
                return;
            if(i&&num[i]==num[i-1] && i>order) 
                continue; // check duplicate combination
            subresult.push_back(num[i]),
            dfs(i+1,target-num[i],subresult,num); // recursive componenet
            subresult.pop_back();
        }
    }
    
private:    
    vector<vector<int > > result;    
};




注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50853069

原作者博客:http://blog.csdn.net/ebowtang

本博客LeetCode题解索引:http://blog.csdn.net/ebowtang/article/details/50668895

你可能感兴趣的:(LeetCode,C++,面试,二叉树,回溯法)