1 题目描述
Given a set of candidate numbers (C) (without duplicates) 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.
- The solution set must not contain duplicate combinations.
难度:Medium
2 题目样例
For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:
[
[7],
[2, 2, 3]
]
3 题意分析
有一个正整数集合C和一个正整数目标T。现从C中选出一些数,使其累加和恰好等于T(C中的每个数都可以取若干次),求所有不同的取数方案。
注意正整数集合中可能存在重复的数字,而这些数字用于组合的时候,会产生重复的排列。题目要求相同的排列只出现一次。
4 思路分析
这个问题我以前是见过的…NYOJ上出现过题设和本题极其相似的部分和问题。用深度优先搜索可以解决。
(PS:这题和上学期算法课上反复操练的整数划分问题也有些相似,可以尝试DP解法。)
1.DFS解法:
先排序,再利用unique进行去重,最后DFS搜索最后结果即可。
代码实现如下
class Solution
{
public:
vector<int> temp;
vector<vector<int> > result;
void DFS(vector<int> &candidates, vector<int> &temp, size_t index, int target)
{
if (target == 0)
{
result.push_back(temp);
return;
}
else
{
for (size_t i = index; i < candidates.size(); i++)
{
if (candidates[i] > target)
return;
temp.push_back(candidates[i]);
DFS(candidates, temp, i, target - candidates[i]);
temp.pop_back();
}
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
sort(candidates.begin(), candidates.end());
candidates.erase(unique(candidates.begin(),candidates.end()),candidates.end());
DFS(candidates, temp, 0, target);
return result;
}
};
2.DP解法:
思想类似于经典的子集和问题。
代码实现如下(直接使用讨论区里的代码)
class Solution
{
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> result;
int size = candidates.size();
if (size == 0) return result;
sort(candidates.begin(), candidates.end());
vector<vector<vector<int>>> dp(target + 1, vector<vector<int>>());
dp[0].push_back(vector<int>());
for (int i = 1; i <= target; ++i) {
for (int j = 0; j < size && candidates[j] <= i; ++j) {
for (int k = 0; k < dp[i - candidates[j]].size(); ++k) {
vector<int> temp = dp[i - candidates[j]][k];
if (temp.size() && (temp[temp.size() - 1] > candidates[j])) continue;
temp.push_back(candidates[j]);
dp[i].push_back(temp);
}
}
}
return dp[target];
}
};
5 后记
不知道为什么,本题目DP解法反而要比深搜解法慢上许多……