Combination Sum

来源:互联网 发布:qq群关系数据库 编辑:程序博客网 时间:2024/06/05 19:44
Problem:

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 (a1a2, … , 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] 

    不难看出,这道题用递归求解比较简单。首先,candidates数组可能是无序的,为了使结果按升序排列,需要先对candidates数组进行排序。从最大(或最小)的candidate开始,对于target=k*candidate+remain。如果remain=0,则在返回结果中添加包含k个candidate的解,如果remain>0,则先求解combinationSum(candidates,remain),注意只能在小于(大于)candidate的元素中搜索解,如果结果不为空,则在每一个解中添加k个candidate。最后合并所有可行的k下的解并返回。
Solution:
public class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target)     {
        if(candidates==null||candidates.length==0)
             return new ArrayList<>();
        Arrays.sort(candidates);
        return subCombination(candidates,candidates.length-1,target);
    }
    
    private List<List<Integer>> subCombination(int[] candidates,int p, int target)     {
        if(target<candidates[0])
             return new ArrayList<>();
        int l = 0,r = p,m;
        while(l<r-1)
        {
             m = (l+r)/2;
             if(candidates[m]>target)
                 r = m;
             else 
                 l = m;
        }
        if(candidates[r]<=target)
             l = r;
        List<List<Integer>> res = new ArrayList<>();
        
        for(int i=0;i<=target/candidates[l];i++)
        {
             int remain = target-i*candidates[l];
             if(remain==0)
             {
                 List<Integer> arr = new ArrayList<>();
                 for(int j=0;j<i;j++)
                     arr.add(candidates[l]);
                 res.add(arr);
             }
             else
             {
                 if(l>0)
                 {
                     List<List<Integer>> tmp = new ArrayList<>();
                     tmp = subCombination(candidates,l-1, remain);
                     if(tmp.size()>0)
                    {
                       for(List<Integer> list:tmp)
                       {
                          for(int j=0;j<i;j++)
                          list.add(candidates[l]);
                       }
                       res.addAll(tmp);
                    }
                 }
             }
        }
        return res;
    }
}
0 0
原创粉丝点击