[0039] 组合总和
- GitHub
- http://leetcode.xuezhisd.top/post/dd61a707.html
- https://leetcode.com/problems/combination-sum
- https://leetcode-cn.com/problems/combination-sum
题目描述
给定一个无重复元素的数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的数字可以无限制重复被选取。
说明:
- 所有数字(包括
target
)都是正整数。 - 解集不能包含重复的组合。
示例 1:
输入: candidates =[2,3,6,7],
target =7
, 所求解集为: [ [7], [2,2,3] ]
示例 2:
输入: candidates = [2,3,5],
target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
Related Topics
题目解析
- 完全01背包问题
不确定性
- 整数的范围
- 数字的范围
- 数字是否会重复
- candidates数组大小
- 以上题目中虽然都有,审题要清楚不能想当然
方法一:逐个尝试法
分析
- 对于每个数字采取选择0,1,2,。。。n的做法
- 尝试过程中注意剪枝
思路
利用完全01背包
伪代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17void dfs(dep, candidates, select, target)
{
if(target<0) return; // 由于被选数都是正数,无答案
if(target==0) {// 答案满足
res.add(select);
return;
}
if(dep >= candidates.size()) return;// 所有的数字都用完了
// 选择当前数字
select.push(candidates[dep]);
dfs(dep, candidates, select, target-candidates[dep]); // 由于当前这个数还有可能被选择,所以dep 还停留在当前。
select.pop();
// 不选择当前数
dfs(dep+1, candidates, select, target);
}
注意
- 要考虑整数加减法有可能溢出,根据题目给出的条件,应该不会有这种情况
知识点
- 01背包
- 暴力
- dfs
复杂度
- 时间复杂度O(NV), N是数组长度,V是target大小
- 空间复杂度O(V), 代表递归深度
代码
1 | typedef long long lld; |