题目描述
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。 
题解
有一说一,我是真的不喜欢递归。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | vector<vector<int>>res = {}; vector<int> candidates1; int mymin; void dfs(int target, vector<int>& keepin,int index) { 	if (!target) 	{ 		res.push_back(keepin); 		return; 	} 	if (target < mymin)return; 	for (int i=index;i<candidates1.size();i++) 	{ 		keepin.push_back(candidates1[i]); 		dfs(target - candidates1[i], keepin,i); 		keepin.pop_back(); 	} } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { 	candidates1= candidates; 	vector<int>::iterator myMin = min_element(candidates.begin(), candidates.end()); 	mymin = *myMin; 	vector<int> keepin = {}; 	dfs(target, keepin,0); 	return res; }
  | 
 
问题描述
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
题解
和上面那道题的区别,不能有重复元素,那index每次就往前走一步,但问题是vector里面有重复元素,这样最后找出来的vector里面就会有重复的vector,暂时想到的方法是每找到一个vector,进行排序后加入set进行去重。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | class Solution { set<vector<int>>res = {}; vector<int> candidates1; int mymin; int v_size; vector<int> tmp; void dfs(int target, vector<int>& keepin, int index) { 	if (!target) 	{ 		tmp = keepin; 		sort(tmp.begin(), tmp.end()); 		 		res.insert(tmp); 		return; 	} 	if (target < mymin)return; 	for (int i = index; i<v_size; i++) 	{ 		keepin.push_back(candidates1[i]); 		dfs(target - candidates1[i], keepin, i+1); 		keepin.pop_back(); 	} } public:     vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {         	candidates1 = candidates; 	vector<int>::iterator myMin = min_element(candidates.begin(), candidates.end()); 	mymin = *myMin; 	v_size = candidates.size(); 	vector<int> keepin = {}; 	dfs(target, keepin, 0); 	vector<vector<int>> v; 	for (auto i = res.begin(); i != res.end(); i++) 		v.push_back(*i); 	return v;     } };
  | 
 
浪费在去重上面的时间太多了,先对candidates排序,然后在回溯之前,对下一位数字判断,如果是相同的,就舍弃;因而不会有重复的集合出现。而且数据没有丢失,这是因为它的上个数在递归过程中能用到它(若它满足条件)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | vector<vector<int>>res = {}; vector<int> candidates1; int mymin,v_size; void dfs(int target, vector<int>& keepin, int index) { 	if (!target) 	{ 		res.push_back(keepin); 		return; 	} 	if (target < mymin)return; 	for (int i = index; i<v_size; i++) 	{ 		keepin.push_back(candidates1[i]); 		dfs(target - candidates1[i], keepin, i+1); 		int j = i+1; 		while (j < v_size) 		{ 			if (candidates1[i] == candidates1[j]) 				i = j; 			else 				break; 			j++; 		} 		keepin.pop_back(); 	} } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { 	candidates1 = candidates;  	sort(candidates1.begin(), candidates1.end()); 	v_size = candidates.size(); 	if (!v_size)return res; 	vector<int>::iterator myMin = min_element(candidates.begin(), candidates.end()); 	mymin = *myMin; 	vector<int> keepin = {}; 	dfs(target, keepin, 0); 	return res; }
  |