Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7c7c4cb

Browse files
committed
Create 39.组合总和(中等).md
1 parent 8d1a009 commit 7c7c4cb

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

Algorithm/39.组合总和(中等).md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
```text
2+
题目: 给定一个无重复元素的数组candidates和一个目标数target,找出candidates中所有可以使数字和为target的组合;
3+
candidates 中的数字可以无限制重复被选取;
4+
说明:
5+
所有数字(包括 target)都是正整数;
6+
解集不能包含重复的组合;
7+
示例 1:
8+
输入:candidates=[2,3,6,7],target=7,所求解集为:
9+
[
10+
[7],
11+
[2,2,3]
12+
]
13+
1.递归回溯法:
14+
[1]思路:
15+
(1)使用递归方式,则需要先考虑递归方法参数:
16+
1)给定的候选数组(candidates)和目标数(target)必不可少;
17+
2)由于最终返回嵌套集合,则嵌套结果集需要在所有递归方法中传递;
18+
3)嵌套结果集的内部集合需要在递归方法中不断添加数,因此内部结果集也需要;
19+
(2)由于使用的是递归,因此递归方法中要考虑递归的终止条件;
20+
(3)再就是考虑什么情况下添加符合条件的集合到结果集中,什么时候需要进行递归操作;
21+
(4)由于是回溯法,需要在遍历中递归,当不满足条件时才可尝试下一个再递归测试;
22+
[2]实现:
23+
class Solution {
24+
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
25+
List<List<Integer>> result = new ArrayList<>();
26+
backtrack(candidates, result, target, new ArrayList<>(), 0);
27+
return result;
28+
}
29+
// 递归回溯
30+
private static void backtrack(int[] candidates, List<List<Integer>> result,
31+
int target, List<Integer> list, int start) {
32+
// 递归的终止条件
33+
if (target < 0) {
34+
return;
35+
}
36+
// 符合条件时,添加到结果集中
37+
if (target == 0) {
38+
// 该list全局独一份,添加结果集时需要拷贝添加
39+
result.add(new ArrayList<>(list));
40+
} else {
41+
for (int i = start; i < candidates.length; i++) {
42+
list.add(candidates[i]);
43+
backtrack(candidates, result, target - candidates[i], list, i);
44+
// 由下一层级回溯到该层级,说明该层级加入的元素不符合条件
45+
//(符合条件的在子层级已经添加到结果集了)
46+
list.remove(list.size() - 1);
47+
}
48+
}
49+
}
50+
}
51+
[3]复杂度分析:
52+
(1)时间复杂度: O(N^H),N为数组长度,H为最大递归深度
53+
(2)空间复杂度: O(N)
54+
```

0 commit comments

Comments
 (0)