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++;//跳过相同结果
}
}