Leetcode Combination Sum I & II

来源:互联网 发布:魅族安卓数据dns修改 编辑:程序博客网 时间:2024/05/17 01:40

Problem 1: Combination Sum I

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times.

Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, � , ak) must be in non-descending order. (ie, a1 ? a2 ? � ? ak). The solution set must not contain duplicate combinations.

For example, given candidate set 2,3,6,7 and target 7, A solution set is: [7]  [2, 2, 3]

Solve the problem on leetcode

分析:

很像传统的硬币问题,我们同样运用Subset和Permutation的思路,只需要考虑两个问题:

1. 什么时候返回?

2. 递归的时候传入什么样的参数

对于上面第二点,我们不妨可以这么想,如果现在和为Target,此时取一个硬币,假设其值为v1,那么下一次,我们其实解决的是相同的子问题,只不过和变成了Target - v1 既然明确了第二点,我们就可以通过Target的取值来确定返回条件

1. 当Target < 0 的时候,无解,return

2. 当Target == 0 的时候,发现解,添加进res里面,然后return

代码如下:

public class Solution {    public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();        ArrayList<Integer> tmp = new ArrayList<Integer>();        Arrays.sort(candidates);        dfs(res,tmp,candidates,target,0);        return res;    }        public void dfs(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> tmp, int[] cand, int target, int pos){        if(target<0) return;        if(target==0){            res.add(new ArrayList<Integer>(tmp));            return;        }        for(int i=pos; i<cand.length; i++){            tmp.add(cand[i]);            dfs(res,tmp,cand,target-cand[i],i);            tmp.remove(tmp.size()-1);        }    }}

需要注意的几点问题:

1.如果不用pos,从数组开头往数组尾巴扫,会出现什么问题? 会出现重复集合的问题,这里的重复不是指顺序完全相同的Set,而是对于每一种组合,我们输出一次就可以了 比如Sum = 3 不加pos会出现 [1,2],[2,1]两种一样的解,我们加入一个pos,限制每次添加只能再添加和这个数字相等或者比这个数字大的数字(数组之前sort过升序排列)这样就会避免问题


Problem 2 : Combination Sum II

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination.

Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, � , ak) must be in non-descending order. (ie, a1 ? a2 ? � ? ak). The solution set must not contain duplicate combinations.

For example, given candidate set 10,1,2,7,6,1,5 and target 8, A solution set is: [1, 7] [1, 2, 5] [2, 6] [1, 1, 6]

Solve the problem on leetcode

同样的思路,只需要注意几个问题:

1. 每个数字只能运用1次,所以再调用dfs的时候,传入的pos,应该是i + 1

2. 利用同样的思路来防止有重复的Set

while(i<num.length-1&&num[i]==num[i+1]) i++;

代码如下:

public class Solution {    public ArrayList<ArrayList<Integer>> combinationSum2(int[] num, int target) {        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();        ArrayList<Integer> tmp = new ArrayList<Integer>();        Arrays.sort(num);        dfs(res,tmp,num,target,0);        return res;    }        public void dfs(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> tmp, int[] num, int target, int pos){        if(target<0) return;        if(target==0){            res.add(new ArrayList<Integer>(tmp));            return;        }        for(int i=pos; i<num.length;i++){            tmp.add(num[i]);            dfs(res,tmp,num,target-num[i],i+1);            tmp.remove(tmp.size()-1);            while(i<num.length-1&&num[i]==num[i+1]) i++;        }    }}


原创粉丝点击