Leetcode39 Combination Sum

来源:互联网 发布:淘宝星期一 编辑:程序博客网 时间:2024/06/13 20:44

Combination Sum

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]

Solution1

  • 这是一道典型的回溯题。每次都尝试加入一个数,若当前得到的和还不够,则继续加入该数,直到和大于target,如果和等于target则得到一个解,若大于则回溯一个数,然后尝试数组中的下一个数。
import java.util.Arrays;import java.util.ArrayList;import java.util.List;public class Solution {    public List<List<Integer>> combinationSum(int[] candidates, int target) {        Arrays.sort(candidates);        List<List<Integer>> result = new ArrayList<List<Integer>>();        help(candidates,0,target,result,new ArrayList<Integer>());        return result;    }    public void help(int[] candidates,int index,int target,List<List<Integer>> result,List<Integer> item){        if(target==0){            result.add(item);            return;        }        if(target<0||index>=candidates.length) return;        for(int i=index;i<candidates.length;i++){            if(target<candidates[i]) return;//因为数组已经排过序,所以后面的数都没必要再去遍历            List<Integer> temp = new ArrayList<Integer>(item);            temp.add(candidates[i]);            help(candidates,i,target-candidates[i],result,temp);        }            }}

Solution2

  • 理论上,任何递归解法都可以用迭代解法来实现,而迭代一般要借用栈的实现,这里就是用一个栈来记录存入数组中的下标。
import java.util.Arrays;import java.util.ArrayList;import java.util.List;import java.util.Stack;public class Solution {    public List<List<Integer>> combinationSum(int[] candidates, int target) {        Arrays.sort(candidates);        List<List<Integer>> result = new ArrayList<List<Integer>>();        List<Integer> item = new ArrayList<Integer>();        Stack<Integer> indexes = new Stack<Integer>();        for(int i=0,sum=0;i<candidates.length||!indexes.empty();){             if(i<candidates.length){                while(sum+candidates[i]<target){                    sum += candidates[i];                    indexes.push(i);                    item.add(candidates[i]);                }                if(sum+candidates[i]==target){                    List<Integer> item1 = new ArrayList<Integer>(item);                    item1.add(candidates[i]);                    result.add(item1);                }            }            if(indexes.empty()) return result;            i = indexes.pop();            sum -= candidates[i++];            item.remove(item.size()-1);        }        return result;          }}

Solution3

  • 这道题实际和找零钱问题本质上是一样的,而找零钱是一个典型的动态规划的解法,因此本题可以用动态规划来解
import java.util.Arrays;import java.util.ArrayList;import java.util.HashMap;public class Solution {    public List<List<Integer>> combinationSum(int[] candidates, int target) {        ArrayList<List<Integer>> result = new ArrayList<List<Integer>>();        if(candidates.length==0) return result;        result.add(new ArrayList<Integer>());        HashMap<Integer,List<List<Integer>>> dp = new HashMap<Integer,List<List<Integer>>>();        dp.put(0,result);        Arrays.sort(candidates);        for(int sum=candidates[0];sum<=target;sum++){            result = new ArrayList<List<Integer>>();            for(int i=candidates.length-1;i>=0;i--){                if(!dp.containsKey(sum-candidates[i])) continue;                for(List<Integer> item:dp.get(sum-candidates[i])){                    if(item.size()>0&&candidates[i]<item.get(item.size()-1)) continue;//只将升序的序列加入,解决序列重复问题                    ArrayList<Integer> temp = new ArrayList<Integer>(item);                    temp.add(candidates[i]);                    result.add(temp);                }                if(i == candidates.length-1) dp.remove(sum-candidates[i]);//将不再需要的去掉,更节省空间            }            if(!result.isEmpty()) dp.put(sum,result);        }        return dp.get(target)==null?new ArrayList<List<Integer>>():dp.get(target);    }}
0 0
原创粉丝点击