if (i != index && num[i] == num[i - 1]) continue;
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]
leetcode中Combination总共有四道题,总体思想上都是想通的,均是利用DFS,DFS方法的结构为:
void DFS(){
if(满足条件) 结束并push_back
else{
for()循环遍历{
push_back;
DFS(下一层);
pop_back();
}
}
}
因为元素可以重复,所以在DFS递归时,不需要进入下一层,利用的条件为target是否依旧大于0:
如果大于0则继续DFS;
如果等于0则表明已经找到了合适的解;
如果小于0则表示已经过头,可以结束;
另外,因为DFS耗时巨大,所以剪枝可以有效的提高效率
class Solution {
public:
void com(vector<int> candidates, int index, int target, vector<vector<int>> &ans, vector<int> &temp, int n)
{
if( 0 >target)return;
if( 0 ==target){
ans.push_back(temp);
return;
}
for(int i= index; i<n;i++){
if(target>= candidates[i]){ //剪枝
temp.push_back(candidates[i]);
com(candidates, i, target- candidates[i], ans, temp, n);
temp.pop_back();
}
}
}
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
int n= candidates.size();
sort(candidates.begin(),candidates.end());
vector<vector<int>> ans;
vector<int> temp;
com(candidates, 0, target, ans, temp, n);
return ans;
}
};
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]
II增加了限制条件,每个数字智能用一次,相对于I,只要DFS递归时进入下一层,且增加判断是否有重复元素就好
不必担心
if (i != index && num[i] == num[i - 1]) continue;
会让如(1, 1, 6)这样的消失,因为排除的相同项是同层的,而此处的两个1为不同层,因此不会被排除掉
II的难度增加了,不剪枝会超时,I的时候还不会出现这种情况
class Solution
{
public:
vector<vector<int> > ans;
vector<int> temp;
vector<vector<int> > combinationSum2(vector<int> &num, int target)
{
sort(num.begin(), num.end());
combination(num, 0, target);
return ans;
}
private:
void combination(const vector<int> &num, int index, int target){
if (target == 0){
ans.push_back(temp);
return;
}
else{
for (int i = index; i < num.size(); i++){
if (i != index && num[i] == num[i - 1]){
continue;
}
if (target >= num[i]){ //此处需要剪枝
temp.push_back(num[i]);
combination(num, i + 1, target - num[i]);
temp.pop_back();
}
}
}
}
};