- Combination Sum
中文English
Given a set of candidtate numbers candidates and a target number target. Find all unique combinations in candidates where the numbers sums to target.
The same repeated number may be chosen from candidates unlimited number of times.
Example
Example 1:
Input: candidates = [2, 3, 6, 7], target = 7
Output: [[7], [2, 2, 3]]
Example 2:
Input: candidates = [1], target = 3
Output: [[1, 1, 1]]
Notice
All numbers (including target) will be positive integers.
Numbers in a combination a1, a2, … , ak must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak)
Different combinations can be in any order.
The solution set must not contain duplicate combinations.
解法1:DFS
DFS 回溯稍微变形了一下。注意剪枝,另外for循环里面要分两种情况处理,因为每个数都可以重复。
class Solution {
public:
/**
* @param candidates: A list of integers
* @param target: An integer
* @return: A list of lists of integers
*/
vector<vector<int>> combinationSum(vector<int> &candidates, int target) {
vector<vector<int>> results;
vector<int> sol;
if (candidates.empty()) {
results.push_back(vector<int>());
return results;
}
sort(candidates.begin(), candidates.end());
helper(candidates, target, 0, sol, results);
return results;
}
void helper(vector<int> &candidates, int target, int index, vector<int> &sol, vector<vector<int>> &results) {
if (target == 0) {
results.push_back(sol);
return;
}
if (index == candidates.size()) return;
if (target < candidates[index]) return; //剪枝
for (int i = index; i < candidates.size(); ++i) {
sol.push_back(candidates[i]);
if (target >= candidates[i]) {
helper(candidates, target - candidates[i], i, sol, results);
} else {
helper(candidates, target - candidates[i], i + 1, sol, results);
}
sol.pop_back();
}
}
};
解法2:类似subset。注意这里不需要pos参数,因为每个数字会被用到多次,所以helper()里面的for循环每次都从0开始,所以pos也没什么用了。
class Solution {
public:
/**
* @param candidates: A list of integers
* @param target: An integer
* @return: A list of lists of integers
* we will sort your return value in output
*/
vector<vector<int>> combinationSum(vector<int> &candidates, int target) {
int len = candidates.size();
vector<int> sol;
set<vector<int>> sets;
helper(candidates, target, 0, sol, sets);
vector<vector<int>> sols(sets.begin(), sets.end());
return sols;
}
private:
void helper(vector<int> &candidates, int target, int sum, vector<int> &sol, set<vector<int>> &sets) {
if (sum > target) return; //all numbers are positive
if (sum == target) {
vector<int> sol2(sol); //注意这里要用sol2备份,因为sol总共只有一个备份,会因为排序而变化,而后面的递归还会用到sol,这样里面的顺序就乱了。
sort(sol2.begin(), sol2.end());
sets.insert(sol2);
return;
}
for (int i = 0; i < candidates.size(); i++) {
//if (i > 0 && candidates[i] == candidates[i - 1]) continue; //用了set后这个就不需要了。
sol.push_back(candidates[i]);
helper(candidates, target, sum + candidates[i], sol, sets);
sol.pop_back();
}
return;
}
};