combination Sum

题目描述

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为:

[[7],[2,2,3]]

主要思路

还是DFS+剪枝的套路,模板在上一篇中已经描述过了,所以这个地方直接给出AC的代码,所有的问题均在注释里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public:
vector<vector<int>> result;
vector<int>path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {
// 如果和已经大于Targt 直接跳出
if (sum > target) {
return;
}
// 符合条件,加入到结果result中取
if (sum == target) {
result.push_back(path);
return;
}

// 这里i 依然从 startIndex开始,因为求的是组合,如果求的是排列,那么i每次都从0开始,跟上一次是一样的,求组和是从Startindex 开始,而且元素是可重复的,所以不存在装在数组进行存储
for (int i = startIndex; i < candidates.size(); i++) {
sum += candidates[i];//进行操作
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i); // 关键点在这里,不用i+1了,表示可以重复读取当前的数
sum -= candidates[i];//恢复现场
path.pop_back();

}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates,target,0,0);
return result;
}
};

这几日做的都是DFS+回溯剪枝的题目,其实主要还是套模板,不过主要区分的是求排列,还是求组合,然后区分开始进行递归的时候,开始的节点的下标,以及每次递归的时候的长度是否叠加,即可