给定一个数组 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]
]
思路跟上一题基本相似,因为每一个只能用一次,故想到用Boolean来辅助记录解
//这个解法不是一个优雅的解法,但是先AC,优雅的解法肯定是在生成解的时候就判重
class Solution {
Set<List<Integer>> set=new HashSet<>();
boolean [] v=new boolean[100];
public void robot(int idx,int [] nums,int target){
if(target==0){
//拼答案
List<Integer> res=new ArrayList<>();
for(int i=0;i<nums.length;i++){
if(v[i]){
res.add(nums[i]);
}
}
set.add(res);
return;
}
if(target<0||idx>=nums.length)
return;
v[idx]=true;
robot(idx+1,nums,target-nums[idx]);//选择这个数并且记录下来
v[idx]=false;
robot(idx+1,nums,target);//不选这个数
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> ans=new ArrayList<>();
Arrays.sort(candidates);
robot(0,candidates,target);
for(List<Integer> s:set)//这个做法有点繁琐,不优雅,最好在生成解的时候就去重
ans.add(s);
return ans;
}
}