【LeetCode】39. Combination Sum (2 solutions)
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成员的过程中,如果candidates[i]是组成target的成员之一,那么寻找target-candidates[i]的子问题与原题就完全一致,因此是典型的递归。
参数列表中:result设为全局变量,用于记录所有可行的路径,因此使用引用(&);curPath是每次递归栈中独立部分,因此使用拷贝复制
解法一:使用map去重
class Solution { public: vector<vector<int> > combinationSum(vector<int> &candidates, int target) { sort(candidates.begin(), candidates.end()); vector<vector<int> > ret; map<vector<int>, bool> m; vector<int> cur; Helper(ret, cur, candidates, target, m, 0); return ret; } void Helper(vector<vector<int> >& ret, vector<int> cur, vector<int> &candidates, int target, map<vector<int>, bool> &m, int ind) { if(target == 0) { if(m[cur] == false) { ret.push_back(cur); m[cur] = true; } } else { for(int i = ind; i < candidates.size() && candidates[i] <= target; i ++) {// for each candidate int val = candidates[i]; cur.push_back(val); Helper(ret, cur, candidates, target-val, m, i); // duplication allowed cur.pop_back(); } } } };
解法二:
稍作分析可知,重复结果的原因在于candidates中的重复元素。
因为我们默认每个位置的元素可以重复多次,而不同位置的元素是不同的。
对candidates的排序及去重的目的就是防止结果的重复,比如7 --> 2,2,3/2,3,2/3,2,2
注:去重函数unique的用法
1、先排序,因为unique只会去掉连续元素中的重复元素
sort(candidates.begin(), candidates.end());
2、调用unique函数
vector<int>::iterator iter = unique(candidates.begin(), candidates.end());
执行完毕之后,返回的iter指向去重之后新数组的尾部,
例如:1,2,2,4,4,5
得到:1,2,4,5,?,?
^
iter
3、最后删除iter到end()之间的所有元素
candidates.erase(iter, candidates.end());
class Solution { public: vector<vector<int> > combinationSum(vector<int> &candidates, int target) { sort(candidates.begin(), candidates.end()); vector<int>::iterator iter = unique(candidates.begin(), candidates.end()); candidates.erase(iter, candidates.end()); vector<vector<int> > ret; vector<int> cur; Helper(ret, cur, candidates, target, 0); return ret; } void Helper(vector<vector<int> >& ret, vector<int> cur, vector<int> &candidates, int target, int pos) { if(target == 0) { ret.push_back(cur); } else { for(int i = pos; i < candidates.size() && candidates[i] <= target; i ++) { //candidates[i] included cur.push_back(candidates[i]); //next position is still i, to deal with duplicate situations Helper(ret, cur, candidates, target-candidates[i], i); //candidates[i] excluded cur.pop_back(); } } } };