描述
给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。
注意事项
所有的数字(包括目标数字)均为正整数。
元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
解集不能包含重复的组合。
样例
给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 ,
解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]
和数字组合的区别在于本题候选数字不能重复调用,候选数字集合不能进行去重,用样例来说明,两个1同时出现可以,只出现一个时要选代表,选代表的方法和带有重复元素的子集那题一样
代码
public class Solution {
/**
* @param num: Given the candidate numbers
* @param target: Given the target number
* @return: All the combinations that sum to target
*/
public List<List<Integer>> combinationSum2(int[] num, int target) {
List<List<Integer>> results = new ArrayList<>();
if (num == null || num.length == 0) {
return results;
}
Arrays.sort(num); //Arrays.sort()方法用于对象数组按用户自定义规则排序.
List<Integer> combinations = new ArrayList<>();
helper(num, 0, results, combinations, 0, target);
return results;
}
private void helper(int[] num,
int startIndex,
List<List<Integer>> results,
List<Integer> combinations,
int sum,
int target) {
//递归出口
if (sum == target) {
results.add(new ArrayList<Integer>(combinations));
return;
}
for (int i = startIndex; i < num.length; i++) {
if (i != 0 && num[i] == num[i - 1] && i > startIndex) {
continue;
}
if (target < sum) {
break;
}
combinations.add(num[i]);
helper(num, i + 1, results, combinations, sum + num[i], target);
combinations.remove(combinations.size() - 1);
}
}
}
PS:
最后几行也可以这么写,只要注意将sum的值还原就行了
combinations.add(num[i]);
sum += num[i];
helper(num, i + 1, results, combinations, sum, target);
sum -= num[i];
combinations.remove(combinations.size() - 1);
还可以这么写,实际上都一样:
private void helper(int[] candidates,
int startIndex,
List<Integer> combination,
int target,
List<List<Integer>> results) {
if (target == 0) {
results.add(new ArrayList<Integer>(combination));
return;
}
for (int i = startIndex; i < candidates.length; i++) {
if (i != startIndex && candidates[i] == candidates[i - 1]) {
continue;
}
if (target < candidates[i]) {
break;
}
combination.add(candidates[i]);
helper(candidates, i + 1, combination, target - candidates[i], results);
combination.remove(combination.size() - 1);
}
}