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 }