39. Combination Sum 40 Combination Sum 2(Array, DFS)
39. Combination Sum
Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [2,3,6,7],
target = 7
A solution set is:
[
[7],
[2,2,3]
]
思路:依舊使用DFS,因為每個元素可以重複使用多次,所以呼叫的時候從當前位置開始。用target儲存當前值,如果小於零就去掉最後一個元素並回溯,如果等於零就加入res,如果大於零就繼續遞迴。一開始我將迴圈每次都從0開始,就會出現【2,2,3】,【2,3,2】,【3,2,2】的結果。因此首先對陣列排序,然後向前搜尋不重複。
public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); if(candidates==null ||candidates.length==0) return res; List<Integer> tmp = new ArrayList<Integer>(); Arrays.sort(candidates); doCombine(candidates, target,0, tmp, res); return res; } private void doCombine(int[] nums, int target, int pos,List<Integer> tmp, List<List<Integer>> res){ for(int i=pos;i<nums.length;i++){ target = target - nums[i]; tmp.add(nums[i]); if(target<=0){ if(target==0) res.add(new ArrayList<Integer>(tmp)); tmp.remove(tmp.size()-1); target = target + nums[i]; return; } doCombine(nums,target,i,tmp,res); tmp.remove(tmp.size()-1); target = target + nums[i]; } }
40. Combination Sum 2
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
Each number in candidates
may only be used once in the combination.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[10,1,2,7,6,1,5]
, target =8
, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
思路:
區別在於每個元素只能用一次。所以遞迴是應該是i+1.
為了避免重複,首先對陣列排序,然後連續兩個相同元素會產生相同結果,所以獎後一個元素跳過,這裡的方法和permutation2中用到的一樣。
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
if(candidates==null ||candidates.length==0)
return res;
List<Integer> tmp = new ArrayList<Integer>();
Arrays.sort(candidates);
doCombine(candidates, target,0, tmp, res);
return res;
}
private void doCombine(int[] nums, int target, int pos,List<Integer> tmp, List<List<Integer>> res){
for(int i=pos;i<nums.length;i++){
target = target - nums[i];
tmp.add(nums[i]);
if(target<=0){
if(target==0)
res.add(new ArrayList<Integer>(tmp));
tmp.remove(tmp.size()-1);
target = target + nums[i];
return;
}
doCombine(nums,target,i+1,tmp,res);//注意是i+1
tmp.remove(tmp.size()-1);
target = target + nums[i];
while(i<nums.length-1 && nums[i]==nums[i+1])
i++;//跳過相同結果
}
}