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:
For example, given candidate set 2,3,6,7
and target 7
,
A solution set is:
[7]
[2, 2, 3]
class Solution { struct Info { vector<pair<int, int>>pre;//pair<int,int>里的first代表sinnums里的index,second代表个数 int remainsize;//剩余的数字个数 int remainvalue;//剩余的值 }; vector<vector<int>>re; void choose_one(int&k, vector<Info>&candi, vector<int>candidates) { vector<Info>newcandi; if (k == 1) { for (int i = 0; i < candi.size(); i++)//考虑0 if (candi[i].remainvalue%candi[i].remainsize == 0) { int nxtnum = candi[i].remainvalue / candi[i].remainsize; if (nxtnum>candidates[candi[i].pre.back().first] && find(candidates.begin(), candidates.end(), nxtnum) != candidates.end()) { vector<int>aa; for (int j = 0; j < candi[i].pre.size(); j++) for (int h = 0; h < candi[i].pre[j].second; h++) aa.push_back(candidates[candi[i].pre[j].first]); for (int j = 0; j < candi[i].remainsize; j++) aa.push_back(nxtnum); re.push_back(aa); } } k--; return; } else { for (int i = 0; i < candi.size(); i++) { for (int j = 1; j <= candi[i].remainsize - k + 1; j++) { for (int h = candi[i].pre.back().first + 1; h < candidates.size() - k + 1; h++) { //粗略做判断,减小候选集大小 if (candi[i].remainvalue <= candidates[h] * j + candidates.back()* (candi[i].remainsize - j) && candi[i].remainvalue >= candidates[h] * j + candidates[h + 1] * (candi[i].remainsize - j)) { Info info; info.pre = candi[i].pre; info.pre.push_back(pair<int, int>(h, j)); info.remainsize = candi[i].remainsize - j; info.remainvalue = candi[i].remainvalue - j*candidates[h]; if (info.remainsize>0 && info.remainvalue >= candidates[h + 1] * info.remainsize) newcandi.push_back(info); } } } } k--; candi = newcandi; return; } } public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { if (candidates.empty() || target <= 0) return re; sort(candidates.begin(), candidates.end()); if (candidates.front() > target) return re; for (int i = 0; i < candidates.size(); i++) //答案里只有一种数字 if (target%candidates[i] == 0) { vector<int>aa(target / candidates[i], candidates[i]); re.push_back(aa); } for (int i = 0; i < candidates.size(); i++) { //答案里有k种数字,2<=k<=neednum int need = target / candidates[i]; if (need >= 2) { for (int neednum = 2; neednum <= need; neednum++) for (int k = 2; k <= neednum; k++) { if (candidates.size() - i >= k) { for (int j = 1; j <= neednum - k + 1; j++) { Info inf; inf.pre.push_back(pair<int, int>(i, j)); inf.remainsize = neednum - j; inf.remainvalue = target - j*candidates[i]; vector<Info>candi; candi.push_back(inf); int kk = k - 1; while (kk > 0) choose_one(kk, candi, candidates); } } } } } return re; } };