Combination Sum
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]
Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
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.
10,1,2,7,6,1,5
and target
8
,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
思路:
通过递归来构造排列组合。
其实另一个思路是构造一个特定的进制数。对于第一个问题,可以用二进制来表示,第i个bit为1的时候表示使用这个数,反之表示不使用这个数。然后进行一次循环。第二个问题可以按照每个数字出现的次数来规定进位制度。缺点是可能会进行额外的大量计算,而且会更复杂。
题解:
class Solution {
public:
vector<vector<int>> result;
vector<int> hist;
vector<int> cc;
void generate_combinations(size_t index, int target)
{
if (target == 0)
{
result.push_back(hist);
return;
}
if (index == cc.size())
return;
int usage = 0;
while(target >= 0)
{
generate_combinations(index + 1, target);
++usage;
target -= cc[index];
hist.push_back(cc[index]);
}
for(int i = 0; i < usage; ++i)
hist.pop_back();
}
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
cc.swap(candidates);
sort(begin(cc), end(cc));
result.clear();
hist.clear();
if (cc.empty())
return result;
generate_combinations(0, target);
return result;
}
};
class Solution
{
public:
vector<int> cc;
vector<pair<int, int>> cc_count;
vector<vector<int>> result;
vector<int> history;
void generate_combination (size_t index, int target)
{
if (target < 0)
return;
if (target == 0)
{
result.push_back (history);
return;
}
if (index == cc_count.size())
return;
int i;
for (i = 0; i <= cc_count[index].second; ++i)
{
generate_combination (index + 1, target);
target -= cc_count[index].first;
if (target < 0)
break;
history.push_back (cc_count[index].first);
}
for (int j = 0; j < i; ++j)
history.pop_back();
}
vector<vector<int> > combinationSum2 (vector<int>& num, int target)
{
result.clear();
cc_count.clear();
cc.swap (num);
sort (begin (cc), end (cc));
while (!cc.empty() && cc.back() > target) cc.pop_back();
if (cc.empty())
return result;
int val = cc.front(), count = 1;
for (size_t i = 1; i < cc.size(); ++i)
{
if (cc[i] == val)
++count;
else
{
cc_count.push_back (make_pair (val, count));
val = cc[i], count = 1;
}
}
cc_count.push_back (make_pair (val, count));
generate_combination (0, target);
return result;
}
};