### 39. 组合总和
题意: candidates无重复元素, 可以从待选数组中无限次选中一个数字。
class Solution {
private void dfs(List> res,Listtmp,int []candidates, int target, int cur){
int size = candidates.length;
if(target == 0) {res.add(new ArrayList<>(tmp)); return;}
for(int i=cur;itarget) return;
tmp.add(candidates[i]);
//因为是可以重复取同一个元素所以i不变
dfs(res,tmp,candidates,target-candidates[i],i);
tmp.remove(tmp.size()-1);
}
}
public List> combinationSum(int[] candidates, int target) {
List> res = new ArrayList<>();
Arrays.sort(candidates);
dfs(res,new ArrayList(),candidates,target,0);
return res;
}
}
### 40. 组合总和 II
题意:candidates有重复元素,candidates
中的每个数字在每个组合中只能使用一次。
class Solution {
private void dfs(List> res, int[] candidates, List tmp, int target, int cur){
int size = candidates.length;
if(target==0){res.add(new ArrayList<>(tmp));return;}
for(int i=cur;itarget) return;
//待定数组中有元素重复的,在递归中需要去重
if(i>cur&&candidates[i]==candidates[i-1]) continue;
tmp.add(candidates[i]);
dfs(res,candidates,tmp,target-candidates[i],i+1);
tmp.remove(tmp.size()-1);
}
}
public List> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List> res = new ArrayList<>();
dfs(res,candidates, new ArrayList(),target,0);
return res;
}
}
### 216. 组合总和 III
题意:找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
class Solution {
private void dfs(int cur, int k, int n,List> res,List tmp){
if(tmp.size()==k){if(n==0){res.add(new ArrayList<>(tmp));}return;}
for(int i=cur;i<=9;i++){
tmp.add(i);
dfs(i+1,k,n-i,res,tmp);
tmp.remove(tmp.size()-1);
}
}
public List> combinationSum3(int k, int n) {
List> res = new ArrayList<>();
//从1开始dfs,tmp元素个数达到k时终止dfs,每次n减去当前添加的数值
dfs(1,k,n,res,new ArrayList<>());
return res;
}
}
###377. 组合总和 Ⅳ
class Solution {
public int combinationSum4(int[] nums, int target) {
//爬楼梯问题 楼梯的阶数一共为target,一次可以走的步数为nums[i]。 一共有多少种走法?
int []dp = new int[target+1];
//target为0,待定数组中一个都不选,返回()
dp[0] = 1;
for(int i=1;i<=target;i++){
for(int num:nums){
if(i>=num){
dp[i] += dp[i-num];
}
}
}
return dp[target];
}
}