描述
給出一組候選數字(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);
}
}