Combination Sum

来源:互联网 发布:松下plc编程视频教程 编辑:程序博客网 时间:2024/05/22 17:45

原题:

Given a set of candidate numbers (C)(without duplicates) and a target number (T), find all unique combinations inC 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.
  • 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]]

即从给定数组中找到所有和为给定数的组合,元素可以重复使用。


思考过程:

起初想起的是以前常用的nSum问题的双指针方法,但这个题没有限制元素使用次数以及解集里元素个数,很棘手,个人觉得堪比hard题。后来查了一下,看来得用递归解决。


解题思路:

先去除重复数字,以防止有重复结果:先排序,再用以前的remov duplicate from sorted array算法对其处理。

遍历字典,每次修改target值和begin值进行递归,详情看代码注释。


结果代码:

public List<List<Integer>> combinationSum(int[] candidates, int target) {        Arrays.sort(candidates);//排序        int j = 1;        for (int i = 1;i < candidates.length;i++){//去掉重复         if (candidates[i] != candidates[i - 1])             candidates[j++] = candidates[i];        }        candidates = Arrays.copyOfRange(candidates,0,j);        return recursive(candidates,target,0);    }    public List<List<Integer>> recursive(int[] candidates,int target,int begin){//begin用于避免重复——当字典一个元素设为begin时,它只能从后面元素寻找满足target的元素,不和前面的找,就能避免结果集有重复         List<List<Integer>> ret = new ArrayList<>();        if (target < candidates[0]) return ret;//这种情况没必要执行下去了        for (int i = begin;i < candidates.length;i++){            if (candidates[i] == target){                List<Integer> list = new ArrayList<>();                list.add(candidates[i]);                ret.add(list);                return ret;            }            List<List<Integer>> lists = recursive(candidates,target - candidates[i],i);            for (int j = 0;j < lists.size();j++){//结合深层的递归结果,整理结果集                lists.get(j).add(candidates[i]);                ret.add(lists.get(j));            }        }        return ret;    }

原创粉丝点击