给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
方法:递归
思路:
1,首先对数组进行排序,方便操作并且节省开支;
2,数组[2,3,6,7],target = 7,定义一个存放临时结果的list,每次需要从start元素开始,比如,先将2存入list,然后target就变成7-2=5,再将2放入list,target就变成5-2=3,再将2放入list,target就是3-2=1,然后再拿start位置元素还是2,但是2比1大,所以不行,那么就将list最后一个元素2去掉,然后将下一个元素也就是3存入list,这时候target变成了0,满足条件,将这个list存入结果集res里面;
3,按照第二步所描述的过程,递归迭代这个数组,将符合条件的元素组合全部拿到即可!
class Solution {
public List> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List list = new ArrayList<>();//新建堆栈用来判断
List> res = new ArrayList<>();//结果集
if (candidates == null || candidates.length == 0)
return res;
combin(candidates, 0, target, list, res);
return res;
}
//对数组元素(已排序)进行逐个判断以及加入结果集
private void combin(int[] candidates, int start, int target,List list, List> res) {
//刚好满足则将结果存入结果集
if (target == 0) {
res.add(new ArrayList<>(list));
return;
}
for (int i = start; i < candidates.length; i ++) {
if (candidates[i] <= target) { //判断是否已经大于target
list.add(candidates[i]);//将第一个元素存入
combin(candidates, i, target -candidates[i] , list, res);//继续判断进栈元素
list.remove(list.size() - 1);//不满足则将最后一个元素移除,进栈新元素判断
}
}
}
}
注意:对数组先排序,然后可以判断如果当前元素已经超出,那么后续肯定全部超出,不必浪费时间,可以提升效率!