组合总和Ⅰ

问题陈述

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

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

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

思路实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> combinations=new ArrayList<>();
List<Integer> res=new ArrayList<>();
backtrack(combinations,res,candidates,target,0);
return combinations;
}

private void backtrack(List<List<Integer>> combinations,List<Integer> res,int[] candidates,int target,int start){
if(target==0){
combinations.add(new ArrayList<>(res));
return;
}
for(int i=start;i<candidates.length;i++){
if(candidates[i]<=target){
res.add(candidates[i]);
backtrack(combinations,res,candidates,target-candidates[i],i);
res.remove(res.size()-1);
}
}
}
}

组合总和Ⅱ

问题陈述

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

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。

1
2
3
4
5
6
7
8
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

思路实现

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
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> combinations=new ArrayList<>();
List<Integer> res=new ArrayList<>();
boolean[] visited=new boolean[candidates.length];
Arrays.sort(candidates);
backtrack(combinations,res,candidates,target,0,visited);
return combinations;
}

private void backtrack(List<List<Integer>> combinations,List<Integer> res,int[] candidates,int target,int start,boolean[] visited){
if(target==0){
combinations.add(new ArrayList<>(res));
return;
}
for(int i=start;i<candidates.length;i++){
if(i!=0 && candidates[i]==candidates[i-1] && !visited[i-1] ){
continue;
}
if(candidates[i]<=target){
visited[i]=true;
res.add(candidates[i]);
backtrack(combinations,res,candidates,target-candidates[i],i+1,visited);
res.remove(res.size()-1);
visited[i]=false;
}
}
}
}

组合总和Ⅲ

问题陈述

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。
解集不能包含重复的组合。

1
2
3
4
示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]

思路分析

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
class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> combinations=new ArrayList<>();
List<Integer> res=new ArrayList<>();
backtrack(combinations,res,k,n,1);
return combinations;
}

private void backtrack(List<List<Integer>> combinations,List<Integer> res,int k,int n,int start){
if(k==0 && n==0){//必须先判断此步
combinations.add(new ArrayList<>(res));
return;
}
if(k==0 || n==0){//第二判断
return;
}
for(int i=start;i<=9;i++){

res.add(i);
backtrack(combinations,res,k-1,n-i,i+1);
res.remove(res.size()-1);

}
}
}