40. 组合总和 II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
class Solution {
// 执行用时:20 ms, 在所有 Java 提交中击败了9.11%的用户
// 内存消耗:39.9 MB, 在所有 Java 提交中击败了77.52%的用户
//回溯法
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Deque<Integer> dp = new ArrayDeque<>();
int len = candidates.length;
List<List<Integer>> res = new ArrayList<>();
DP(candidates,len , target, dp, res);
List<List<Integer>> listNew=new ArrayList<List<Integer>>();
for (List<Integer> list : res) {
if(!listNew.contains(list)){
listNew.add(list);
}
}
return listNew;
}
public void DP(int[] candidates,int n, int target, Deque<Integer> dp,List<List<Integer>> res) {
// //dp[n,k],当n=0时,返回当前数组中的数
if(target == 0){
List list = new ArrayList<>(dp);
Collections.sort(list);
res.add(list);
return;
}
if(n == 0){
return;
}
int times = target / candidates[n - 1];
times = Math.min(1,times);
for(int i = 0;i <= times;++i){
for(int j = 0; j < i; ++j){
dp.addLast(candidates[n - 1]);
}
DP(candidates, n - 1,target - candidates[n - 1] * i, dp, res);
for(int j = 0; j < i; ++j){
dp.removeLast();
}
}
return;
}
}