嘿嘿,这道题想起来了。
题目:
给定一个无重复元素的数组 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);
}
}
我也想过,通过排序,减少时间,不知道,效果如何,嘿嘿
2021-8-13 我的清晰思路
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ret=new ArrayList<>();
List<Integer> temp=new ArrayList<>();
combinationSumPass(0,target,0,candidates,ret,temp);
return ret;
}
public void combinationSumPass(int sum,int target,int index, int[] candidates,List<List<Integer>> ret,List<Integer> temp){
if(sum==target){
ret.add(temp);
return;
}
if(temp.size()>=150 || sum>target || index>=candidates.length){
return ;
}
List<Integer> addl=new ArrayList<>(temp);
List<Integer> del=new ArrayList<>(temp);
addl.add(candidates[index]);
combinationSumPass(sum+candidates[index],target,index,candidates,ret,addl);
combinationSumPass(sum,target,index+1,candidates,ret,del);
}
}
哈哈哈