39. 组合总和
题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[[7],[2,2,3]]
代码1:
//回溯法,每次回到当前根节点
class Solution {
public List<List
var list=new ArrayList<List
var arr=new ArrayList
int sum=0;
Arrays.sort(candidates);
backTrack(list,arr,candidates,target,sum,0);
return list;
}
public static void backTrack(List<List<Integer>> alist,List<Integer> arr,int[] acandidates, int atarget,int sum,int t){ //t记录当前为第几个数,,i要不小于t
if(sum==atarget){
var temp=new ArrayList<Integer>(arr);
if(!alist.contains(temp)){
alist.add(temp);}
}
if(sum<atarget){
for(int i=t;i<acandidates.length;i++){
sum+=acandidates[i];
if(sum<=atarget){
arr.add(acandidates[i]);
backTrack(alist,arr,acandidates,atarget,sum,i);
arr.remove(arr.size()-1) ; } //数字和小于目标数
sum-=acandidates[i];
}
}
}
}
代码2://对1进行了优化
class Solution {
public List<List
var list=new ArrayList<List
var arr=new ArrayList
int sum=0;
Arrays.sort(candidates);
backTrack(list,arr,candidates,target,0);
return list;
}
public static void backTrack(List<List<Integer>> alist,List<Integer> arr,int[] acandidates, int atarget,int t){ //此处atarget代表着剩余能放入大小
if(atarget==0){
var temp=new ArrayList<Integer>(arr); //排序之后,每次都从当前i处循环,可以避免重复数组列表
alist.add(temp);
}
if(atarget>0){
for(int i=t;i<acandidates.length;i++){
if(acandidates[i]<=atarget){ //比1少了一个sum,利用剩余大小和当前i的值比较能不能放入,可以减少开销
arr.add(acandidates[i]);
backTrack(alist,arr,acandidates,atarget-acandidates[i],i);
arr.remove(arr.size()-1) ; } //数字和小于目标数
}
}
}
}
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术