上篇博文我們解決了組合總和的問題
LeetCode0039組合總和
現在我們來看第40題
題目描述
這道題與上一問的區別在於:
第 39 題:candidates 中的數字可以無限制重複被選取。
第 40 題:candidates 中的每個數字在每個組合中只能使用一次。
編碼的不同就在於,下一層遞歸的起始索引不一樣。
第 39 題:還從候選數組的當前索引值開始。
第 40 題:從候選數組的當前索引值的下一位開始。
相同之處:解集不能包含重複的組合。
爲了使得解集不包含重複的組合。我們想一想,如何去掉一個數組中重複的元素,除了使用哈希表以外,我們還可以先對數組升序排序,重複的元素一定不是排好序以後的 1 個元素和相同元素的第 1 個元素。根據這個思想,我們先對數組升序排序是有必要的。候選數組有序,對於在遞歸樹中發現重複分支,進而“剪枝”是十分有效的。
Java代碼
class Solution {
private void findCombinationSum2(int[] candidates,int begin,int len,
int residue,Stack<Integer> stack,List<List<Integer>> res){
if(residue==0){
res.add(new ArrayList<>(stack));
return;
}
for(int i=begin;i<len&&residue-candidates[i]>=0;i++){
if(i>begin&&candidates[i]==candidates[i-1]){
continue;
}
stack.add(candidates[i]);
findCombinationSum2(candidates,i+1,len,
residue-candidates[i],stack,res);
stack.pop();
}
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
int len=candidates.length;
List<List<Integer>> res=new ArrayList<>();
if(len==0){
return res;
}
Arrays.sort(candidates);
findCombinationSum2(candidates,0,len,target,new Stack<>(),res);
return res;
}
}