题目:
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有不同组合 ,并以列表形式返回。你可以按任意顺序返回这些组合。candidates 中的同一个数字可以无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
示例1:
![](https://img-blog.csdnimg.cn/img_convert/4ac501d5a9511c8fecd52a862cd2f4d7.png)
示例2:
![](https://img-blog.csdnimg.cn/img_convert/67e658c72cf0442a31eb5d4c627cc7e9.png)
示例3:
![](https://img-blog.csdnimg.cn/img_convert/71694dd77fc71f87862fd5c844041e25.png)
思路:
有三个方法:main方法,combinationSum()方法,dfs()方法。
combinationSum()方法:
两个参数:
int[] candidates:输入的数组;
target:目标值;
返回值:
是List<List<Integer>>类型,表示返回的是一个二维数组,数组里面元素都是Integer整型类型
我们在该方法中声明两个数组,以便后面递归调用dfs()方法传入参数
dfs()方法:
五个参数:
candidates:输入的数组
target:目标值
res:返回的结果
combine:返回结果的子结果
index:数组下标
我们递归时要注意终止(出口)条件,当数组下标index等于数组长度时,即直接retrun
当传入的target==0,即表示已经找到可行解,将combine添加至res中进行输出
当index=0递归完成后,将index+1继续进行递归
main方法:
用键盘输入,依次输入数组和目标值traget
调用combinationSum(),传入实参后输出结果
package Lq_算法练习;
import java.util.ArrayDeque;
import java.util.Scanner;
public class Demo_组合总和 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();//输入数组
int target = in.nextInt();//输入目标值
String[] strArray = str.split(",");//输入的数组用','来分隔
int[] candidates = new int[strArray.length];//声明一个数组长度为strArray.length的数组
for (int i = 0; i < candidates.length; i++) {
candidates[i] = Integer.parseInt(strArray[i]);//将整型数据Integer转换为基本数据类型int
}
//Integer本身是int类型的封装类.意思就是把一个int 类型的数据封装成对象;
//List<Integer>表明List中封装的必须是一个整型
List<List<Integer>> res = combinationSum(candidates, target);
System.out.println(res);
}
//返回值是一个List<List<Integer>>类型,表示返回的是一个二维数组,数组里面元素都是Integer整型类型
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> combine = new ArrayList<>();
// index=0,从第一个元素开始递归
dfs(candidates, target, res, combine, 0);
return res;
}
/*
* candidates:输入的数组
* target:目标值
* res:返回的结果
* combine:返回结果的子结果
* index:数组下标
*/
public static void dfs(int[] candidates, int target, List<List<Integer>> res, List<Integer> combine, int index) {
// index从0开始累加,当index等于数组长度时,表示已经对前index-1个元素(即全部元素)完成递归
if (index == candidates.length) {
//递归终止条件
return;
}
// 每一次递归,当传入的target==0,即表示已经找到可行解,将combine添加至res中进行输出
if (target == 0) {
res.add(new ArrayList<Integer>(combine));
return;
}
// index每次加1进行递归
dfs(candidates, target, res, combine, index + 1);
// 对元素进行判断,若元素小于target,添加元素至combine中
if (target - candidates[index] >= 0) {
combine.add(candidates[index]);
// 改变target值,再次递归,因为每个元素可以被使用多次,所以index不变
//这里的traget就等于其本身减去上面已经添加到combine数组中的元素
dfs(candidates, target - candidates[index], res, combine, index);
// combine要存储每一次的可能结果,所以每次都要进行移除操作,让combine为空,方便下一次操作
combine.remove(combine.size() - 1);//移除数组中最后一个元素,这里只有一个元素,移除便可
}
}
}
运行结果示例:
示例1:
![](https://img-blog.csdnimg.cn/img_convert/649e5864b8568ba9eb1107574a38f824.png)
示例2:
![](https://img-blog.csdnimg.cn/img_convert/890eae981c5aae9ce240d0c785f0e661.png)