LeetCode OJ: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] 

本题需要用到DFS,只不过在在有限搜索的过程中用到了剪枝,使得在优先搜索的过程中一旦遇到了对应的值那么就返回,

不再搜索余下节点。所以这题,首先将数组排序,排序之后再使用DFS加剪枝就可以达到目标。代码如下:

 1 class Solution {
 2 public:
 3     vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
 4         tmpCdd = candidates;
 5         sort(tmpCdd.begin(), tmpCdd.end());
 6         this->target = target;
 7         vector<int> tmpVec;
 8         dfs(0, tmpVec);
 9         return result;
10     }    
11 private:
12     int target;
13     vector<int> tmpCdd;
14     vector<vector<int>> result;
15 private:
16     void dfs(int index, vector<int> & tmpVec)
17     {
18         if(index == tmpCdd.size()) return;    //到达叶节点
19         int tmpSum = accumulate(tmpVec.begin(), tmpVec.end(), 0);
20         if(tmpSum == target){
21             result.push_back(tmpVec);
22             return;
23         }else if(tmpSum > target){//剪枝
24             return;
25         }else{
26             for(int i = index; i < tmpCdd.size(); ++i){//这里从i开始的原因是因为参数可以是重复的
27                 tmpVec.push_back(tmpCdd[i]);
28                 dfs(i, tmpVec);
29                 tmpVec.pop_back();//回溯
30             }
31         }
32     }
33 };

 java版本的如下所示,思想一样,方法有一点不同,这次不对tmpCdd数组中的值每次都求和,而是每递归一次之后将target的值减去一个数传入 下次递归中,代码如下:

 1 public class Solution {
 2     List<List<Integer>> ret = new ArrayList<List<Integer>>();
 3     public List<List<Integer>> combinationSum(int[] candidates, int target) {
 4         Arrays.sort(candidates);
 5         for(int i = 0; i < candidates.length; ++i){
 6             ArrayList<Integer> tmpCdd = new ArrayList<Integer>();
 7             tmpCdd.add(candidates[i]);
 8             dfs(i, tmpCdd, candidates, target - candidates[i]);
 9             tmpCdd.remove(tmpCdd.size() - 1);
10         }
11         return ret;
12     }
13 
14     public void dfs(int index, List<Integer> tmpCdd, int[] candidates, int target){
15         if(index == candidates.length)
16             return;
17         if(target < 0)
18             return; //直接剪枝
19         if(target == 0){
20             ret.add(new ArrayList<Integer>(tmpCdd));
21             return;
22         }else{
23             for(int i = index; i < candidates.length; ++i){
24                 tmpCdd.add(candidates[i]);
25                 dfs(i, tmpCdd, candidates, target - candidates[i]);
26                 tmpCdd.remove(tmpCdd.size() - 1);
27             }
28         }
29     }
30 }

 

posted @ 2015-10-09 22:53  eversliver  阅读(231)  评论(0编辑  收藏  举报