Combination Sum I&&II

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] 

 

需要注意的是题目给出的数据可能是乱序的,由于集合中每个元素可以用一次或多次,但是答案中不能有重复的组合,而且组合中的元素必须是非递减的顺序,因此刚开始需要对candidates进行排序,并且去重,然后对每个元素进行深搜。

深搜的每一步中都有两个选择,对第k个元素我们均可选也可不选

 

 1 class Solution {
 2 public:
 3     vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
 4         vector<int> path;   //存储解
 5         allpath.clear();
 6         sort(candidates.begin(), candidates.end()); //排序
 7         candidates.erase( unique(candidates.begin(), candidates.end()), candidates.end() ); //去重
 8         dfs(candidates, path, 0, target);
 9         return allpath;
10     }
11     
12     void dfs(vector<int>& candidates, vector<int>& path, int k, int target) {
13         if( target == 0 ) { //说明path中的元素相加等于target,这是有效解
14             allpath.push_back(path);
15             return ;
16         }
17         if( k>=candidates.size() || target < 0 ) return ;   //如果元素被搜完,或加上前个元素超出了target,那么是无效解
18         path.push_back(candidates[k]);
19         dfs(candidates, path, k, target-candidates[k]); //加入第k个元素是解之一
20         path.pop_back();
21         dfs(candidates, path, k+1, target); //不要第k个元素的情况
22     }
23     
24 private:
25     vector< vector<int> > allpath;  //记录所有解
26 };

 

还有一种很通俗的算法,直接I&&II都秒杀,对每个子问题的数组中,重复的数字都不计算

 1 class Solution {
 2 public:
 3     vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
 4         vector<int> path;   //存储解
 5         allpath.clear();
 6         sort(candidates.begin(), candidates.end()); //排序
 7         dfs(candidates, path, 0, target);
 8         return allpath;
 9     }
10     
11     void dfs(vector<int>& candidates, vector<int>& path, int k, int target) {
12         if( target == 0 ) { //说明path中的元素相加等于target,这是有效解
13             allpath.push_back(path);
14             return ;
15         }
16         for(int i=k; i<candidates.size() && target>=candidates[i]; ++i) {
17             if( i>k && candidates[i] == candidates[i-1] ) continue; //当前子问题重复的数字不选择不计算
18             path.push_back(candidates[i]);
19             dfs(candidates, path, i, target-candidates[i]); //可选择同一个元素多次
20             path.pop_back();
21         }
22     }
23     
24 private:
25     vector< vector<int> > allpath;  //记录所有解
26 };

 

 

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] 

 
用上面的方法二,只是下次搜索,不搜索当前的元素
 1 class Solution {
 2 public:
 3     vector<vector<int> > combinationSum2(vector<int> &num, int target) {
 4         vector<int> path;
 5         allpath.clear();
 6         sort(num.begin(), num.end());
 7         dfs(num, path, 0, target);
 8         return allpath;
 9     }
10     
11     void dfs(vector<int>& num, vector<int>& path, int k, int target) {
12         if( target == 0 ) {
13             allpath.push_back(path);
14             return ;
15         }
16         for(int i=k; i<num.size() && target>=num[i]; ++i) {
17             if( i>k && num[i] == num[i-1] ) continue;   //当前子问题中,重复的数字不选择
18             path.push_back(num[i]);
19             dfs(num, path, i+1, target-num[i]); //继续搜索下一个元素
20             path.pop_back();
21         }
22     }
23     
24 private:
25     vector< vector<int> > allpath;
26 };

 

posted on 2014-10-05 15:23  bug睡的略爽  阅读(135)  评论(0编辑  收藏  举报

导航