Leetcode 39 Combination Sum 组合总和

嘿嘿,这道题想起来了。

题目:

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

这道题关键点是第一次是【2,3,6,7】里查找7 选了:

1:选了2 【2,3,6,7】中选5

2:不选2【3,6,7】中选7

一次递归:但貌似我的时间有点长;代码如下:

package test;

import java.util.ArrayList;
import java.util.List;

public class LC39Try1
{
	public List<List<Integer>> combinationSum(int[] candidates, int target)
	{
		List<List<Integer>> ret = new ArrayList<List<Integer>>();
		List<Integer> list = new ArrayList<Integer>();
		dpTree(candidates,target,0,0,list,ret);
		return ret;
	}
	public void dpTree(int[] candidates, int target,int start,int sum,List<Integer> list,List<List<Integer>> ret){
		if(sum==target){
			ret.add(new ArrayList<Integer>(list));
			return;
		}
		if(start==candidates.length){
			return;
		}
		if(sum+candidates[start]<=target){
			sum+=candidates[start];
			list.add(candidates[start]);
			dpTree(candidates,target,start,sum,list,ret);
			sum-=candidates[start];
			list.remove(list.size()-1);
		}
		dpTree(candidates,target,start+1,sum,list,ret);
		
	}
	public static void main(String[] args)
	{
		LC39Try1 t = new LC39Try1();
		int[] candidates={2,3,6,7};
		int target=1;
		List<List<Integer>> ret = t.combinationSum(candidates, target);
		for(int i=0;i<ret.size();i++){
			List<Integer> list=ret.get(i);
			for(int j=0;j<list.size();j++){
				System.out.print(list.get(j)+",");
			}
			System.out.println("");
		}
		
	}

}

我看了下,别人的代码,貌似利用循环,可以减少栈的深度,人家的代码如下:

public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> ans = new ArrayList<>();
        search(candidates, 0, target, new Integer[target], 0, ans);
        return ans;
    }
    
    private void search(int[] candidates, int st,
                        int target,
                        Integer[] paper, int len,
                        List<List<Integer>> ans) {
        if (target == 0) {
            Integer[] temp = new Integer[len];
            System.arraycopy(paper, 0, temp, 0, len);
            ans.add(Arrays.asList(temp));
            return;
        }

        for(int i=st; i<candidates.length; i++) {
            if (target < candidates[i]) break;
            paper[len] = candidates[i];
            search(candidates, i, target-candidates[i], paper, len+1, ans);
        }
    }
我也想过,通过排序,减少时间,不知道,效果如何,嘿嘿

猜你喜欢

转载自blog.csdn.net/ata_123/article/details/80898292