给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。
样例
注意
给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 ,
解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]
- 所有的数字(包括目标数字)均为正整数。
- 元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
- 解集不能包含重复的组合。
class Solution { public: map<vector<int>,bool> check; void backtracing(vector<vector<int> >&ret,vector<int> &vec,vector<int> &nums,int cur,int n,int left){ if(left==0){ if(0==check.count(vec)){ //题目要求不准有重复 ret.push_back(vec); check[vec]=true; } return ; } if(cur==n) return ; for(int i=cur;i<n;++i){ if(nums[i]<=left){ vec.push_back(nums[i]); //放入num[i]以后,就去找它后面的元素(i+1),不要回头找 backtracing(ret,vec,nums,i+1,n,left-nums[i]); vec.pop_back(); //有进有出 }else
break; //因为数组是升序的,nums[i]都不符合,那nums[i+1],nums[i+2]...自然不都不会符合了. } } vector<vector<int> > combinationSum2(vector<int> &nums, int target) { vector<vector<int> > ret; vector<int> vec; sort(nums.begin(),nums.end()); //因为题目要求子数组非降序,那么就在这里先排序 int n=nums.size(); backtracing(ret,vec,nums,0,n,target); return ret; } };