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:

扫描二维码关注公众号,回复: 4891664 查看本文章
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++;//跳过相同结果
        }
    }

猜你喜欢

转载自blog.csdn.net/shulixu/article/details/86029303