给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
提示:
1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30
class Solution {
static HashSet<String> temps = new HashSet<>();
static LinkedList<Integer> res;
static List<List<Integer>> allRes;
static int[] _candidates;
static int _target;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
_candidates = candidates;
_target = target;
res = new LinkedList<>();
allRes = new ArrayList<>();
temps = new HashSet<>();
Arrays.sort(_candidates);
dfs(0, 0);
//System.out.println(allRes);
return allRes;
}
private static void dfs(int index, int total) {
if (total > _target) return;
//System.out.println(res);
if (total == _target){
allRes.add(new ArrayList<>(res));
//System.out.println(res);
return;
}
for (int i = index; i < _candidates.length; i++) {
// 累加和 <= 目标值 -> 表示能放入数字
if (_candidates[i] + total <= _target){
// 放入数字
res.add(_candidates[i]);
// 检查此局面是否出现过
if (temps.contains(res.toString())){
// 剪枝,避免重复的局面再次递归
res.removeLast();
continue;
}else{
temps.add(res.toString());
}
// 递归拼接
dfs(i+1, total+_candidates[i]);
// 回溯
res.removeLast();
}else{
break;
}
}
}
}