给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
这道题和上道题比较像,只不过不能重复用
第一次提交犯了一个错误,我直接使用了TreeSet去重,但会覆盖不到有多个同样数且需要多个同样数才能组成结果的时候,去重会抹掉数量信息,我们只要保证在dfs同层不会使用同一个数,结果就不会重复。
private List<List<Integer>> result=new ArrayList();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<Integer> all=Arrays.stream(candidates).sorted().boxed().collect(Collectors.toList());
helper(all,new ArrayList(),0,target);
return result;
}
private void helper(List<Integer> all,List<Integer> cur,int index,int target){
if(target==0){
result.add(cur);
return;
}
for(int i=index;i<all.size() && target>=all.get(i);i++){
if(i>index && all.get(i)==all.get(i-1)) continue;
List<Integer> list=new ArrayList();
list.addAll(cur);
list.add(all.get(i));
helper(all,list,i+1,target-all.get(i));
}
}
错误的
private List<List<Integer>> result=new ArrayList();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Set<Integer> set=new TreeSet();
for(int i:candidates) set.add(i);
helper(new ArrayList(set),new ArrayList(),0,target);
return result;
}
private void helper(List<Integer> all,List<Integer> cur,int index,int target){
if(target==0){
result.add(cur);
return;
}
for(int i=index;i<all.size() && target>=all.get(i);i++){
List<Integer> list=new ArrayList();
list.addAll(cur);
list.add(all.get(i));
helper(all,list,i+1,target-all.get(i));
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。