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]
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;
}
};accepted

本文详细阐述了一种用于寻找给定候选数集中所有可能的组合,这些组合的元素之和等于目标数值的算法。该算法允许重复选择相同的候选数,并确保组合中元素的顺序非递减且不包含重复项。
5万+

被折叠的 条评论
为什么被折叠?



