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.
2,3,6,7
and target
7
,
A solution set is:
[7]
[2, 2, 3]
题目要求找到满足: Sum = Target 条件的数字组合,并且相同的数字可以被多次使用,但是最终结果中要保证不能存在重复的组合。
分析:
1)这个题目可以用BFS来解,也可以使用DFS解,这里使用BFS求解;
2)BFS数据结构设定:
队列:BFS 队列(Queue)用来存储当前的一个组合,队列中每个元素用vector<int>,每个元素的第一个元素表示当前组合的Sum。
3)剪枝条件:当前的Sum>target时,当前的分支就没有必要再词入队进行下次的搜索尝试了;
当前正被考虑是否要加入到当前组合中的集合元素如果小于当前组合中的最大元素,也没有必要再尝试此分支;
求解过程优先要对给定集合candidates进行排序时间花费为O(nlogn);
然后进行BFS,BFS过程中每一步并没有对原有的问题规模进行实质性的减小,属于O(2^n)。
class Solution {
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
vector<vector <int>> res;
int sizeC=candidates.size();
if(sizeC==0){
return res;
}
queue < vector<int> > bfsQueue;
//temp Ans tempAns[0] denote current sum
vector <int> tempAns;
sort(candidates.begin(), candidates.end(), less <int>() );
//initialzie bfs
for(int i=0;i<sizeC;i++){
if(candidates[i]==target){
res.push_back(vector<int>(1,candidates[i]));
break;
}
bfsQueue.push(vector<int>(2,candidates[i]));
}
while(!bfsQueue.empty()){
tempAns=bfsQueue.front();
bfsQueue.pop();
int maxC=tempAns[tempAns.size()-1];
for(int i=0;i<sizeC;i++){
if(maxC<=candidates[i]){
tempAns[0]+=candidates[i];
tempAns.push_back(candidates[i]);
//find one solution
if(tempAns[0]==target){
tempAns.erase(tempAns.begin());
//judge if already in res
int k=0;
for(k=0;k<res.size();k++){
if(tempAns==res[k]){
break;
}
}
if(k==res.size()){
res.push_back(tempAns);
}
break;
}
else{
//keep try
if(tempAns[0]<target){
bfsQueue.push(tempAns);
tempAns.erase(tempAns.end()-1);
tempAns[0]-=candidates[i];
}
}
}
}
}
return res;
}
};