题目描述
给定一个无重复元素的数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的数字可以无限制重复被选取。
说明:
- 所有数字(包括
target
)都是正整数。 - 解集不能包含重复的组合。
来源,leetcode 每日一题 39. 组合总和
例如:ull,null,15,7],
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
解题思路
- 递归: 每次对 target-candidates[i]做递归
-
代码
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
int len = candidates.size();
vector<int> path;
vector<vector<int>> ans;
dfs(candidates,target,0,len,path,ans);
return ans;
}
void dfs(vector<int> &candidates,int target,int begin,int len,vector<int> &path,vector<vector<int>> &ans){
if(target==0){
ans.push_back(path);
return;
}
if(target-candidates[begin]<0){
return;
}
for(int i=begin;i<len;i++){
path.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i,len,path,ans);
path.pop_back();
}
}
};
40. 组合总和 II
给定一个数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
leetcode每日一题 40. 组合总和 Ⅱ
注意点
提高运行时间的一个办法,就是将函数里面的参数变成地址传递,而不是使用值传递。使用值传递,会使用赋值构造函数进行,这个过程是慢的。
代码
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
map<vector<int>, int> answer;
vector<vector<int>> result;
vector<int> path;
dfs(answer, candidates, target, path, 0, candidates.size());
for (map<vector<int>, int>:: iterator it = answer.begin(); it != answer.end(); it++) {
result.push_back(it->first);
}
return result;
}
void dfs(map<vector<int>, int> & answer, vector<int>& candidates, int target, vector<int>& path, int begin, int len) {
if (begin >= len) {
return;
}
for (int i = begin; i < len; i++) {
if (candidates[i] > target) {
return;
}
path.push_back(candidates[i]);
if (target == candidates[i]) {
answer[path] += 1;
path.pop_back();
return;
}
dfs(answer, candidates, target-candidates[i], path, i + 1, len);
path.pop_back();
}
}
};