题目描述
给定一个无重复元素的数组 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]
]
首先这道题拿到我就猜到是回溯法,首先肯定要对数组进行排序一下,然后以
[2,3,5], target = 8为例子,首先是2,我们发现8-2=6>0继续-2=4>0 继续-2=2>0继续-2=0好的,我们把产生的这个临时list放入最后的list,然后弹出最后放入的2,目前是2,然后放入3 = -1<0 好的,继续弹出2,然后=4放入3=1>0放入5<0弹出5,弹出3弹出2,弹出2,然后以此到3,放入三个3后为9>8,因此需要弹出一个三,…之后就是3,5,递归和回溯需要注意的是临时的list就一个,因此当不满足条件时需要弹出,因此每次调用之后都需要弹出
代码(对回溯和递归还是不太熟悉,需要注意啊)
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<Integer> list = new ArrayList<>();//新建堆栈用来判断
List<List<Integer>> 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<Integer> list, List<List<Integer>> 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);//不满足则将最后一个元素移除,进栈新元素判断
}
}
}
排名靠前的代码
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
class Solution {
private void search(int[] candidates, int target, int[] count, List<List<Integer>> res, int n) {
if(target == 0) {
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i <= n; i++) {
for(int j = 0; j < count[i]; j++) {
list.add(candidates[i]);
}
}
res.add(list);
}
if(n == candidates.length || target < candidates[n])
return;
search(candidates, target, count, res, n + 1);
count[n]++;
search(candidates, target - candidates[n], count, res, n);
count[n]--;
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if(candidates == null || candidates.length == 0) {
return new ArrayList<List<Integer>>();
}
Arrays.sort(candidates);
List<List<Integer>> res = new ArrayList<List<Integer>>();
int[] count = new int[candidates.length];
search(candidates, target, count, res, 0);
return res;
}
}