leetcode 39. Combination Sum

来源:互联网 发布:怎样提高淘宝店排名 编辑:程序博客网 时间:2024/05/22 09:45

Given a set of candidate numbers (C(without duplicates) 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.
  • 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]]
这道题我是用递归做的。

public List<List<Integer>> combinationSum(int[] candidates, int target) {List<List<Integer>> res=new ArrayList<List<Integer>>();helper(res, new ArrayList<>(), 0, candidates, target);return res;}public void helper(List<List<Integer>> res,List<Integer> list,int index,int[] nums,int target){if(target==0){res.add(new ArrayList<>(list));return;}if(index>=nums.length){return;}helper(res, list, index+1, nums, target);int theNum=nums[index];int count=1;while(theNum*count<=target){for(int i=0;i<count;i++){list.add(theNum);}helper(res, list, index+1, nums, target-theNum*count);for(int i=0;i<count;i++){list.remove(list.size()-1);}count++;}}
大神也用的递归,更加简洁。因为大神没有跟我一样算某个元素的count,所以在方法内递归没有index+1,因为相同元素可以重复使用。

public List<List<Integer>> combinationSum(int[] nums, int target) {    List<List<Integer>> list = new ArrayList<>();    Arrays.sort(nums);    backtrack(list, new ArrayList<>(), nums, target, 0);    return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums,   int remain, int start){    if(remain < 0) return;    else if(remain == 0) list.add(new ArrayList<>(tempList));    else{         for(int i = start; i < nums.length; i++){            tempList.add(nums[i]);            // not i + 1 because we can reuse same elements            backtrack(list, tempList, nums, remain - nums[i], i);             tempList.remove(tempList.size() - 1);        }    }}
此外,还有大神用DP做,这是个非递归的方法。

使用dp,dp[i] 存储所有和为 i 的结果(所有的 i  < target )。

public class Solution {    public List<List<Integer>> combinationSum(int[] cands, int t) {        Arrays.sort(cands);         List<List<List<Integer>>> dp = new ArrayList<List<List<Integer>>>();        for (int i = 1; i <= t; i++) { // 遍历所有从 1 到t 的 targets             List<List<Integer>> newList = new ArrayList();             // 遍历所有 大小<= i 的元素            for (int j = 0; j < cands.length && cands[j] <= i; j++) {                if (i == cands[j]) newList.add(Arrays.asList(cands[j]));                //得到 target为i-cands[j] 的结果,索引为 target为i-cands[j]                else for (List<Integer> l : dp.get(i-cands[j]-1)) {                    //检查 "是否(cands[j] <= l.get(0))" 来去除重复情况                    if (cands[j] <= l.get(0)) { //保证cl中是递增顺序                        List cl = new ArrayList<>();                        cl.add(cands[j]); cl.addAll(l);                        newList.add(cl);                    }                }            }            dp.add(newList);        }        return dp.get(t-1);    }}


原创粉丝点击