题目
给定一个无重复元素的数组 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]
]
解题思路:
本题采用递归的方式,每次递归重新计算target = target - args[i], 如果target == 0 找到该temp集合,target < 0 将temp 最后一位移除。 建议拿[1,2] 和 target =3 手写每次递归的调用,更直接理解算法思路。
具体代码:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates); //这里排序应该会更快点。
calculate(candidates, 0, target, new ArrayList<Integer>(), res);
return res;
}
/**
* @param args
* @param start
* @param target
* @param temp
* @param res
* @return
*/
public void calculate(int[] args, int start, Integer target, ArrayList<Integer> temp, List<List<Integer>> res) {
// 递归处理思路:1、先找到跳出递归临界点退出。 2、递归操作。
if (target == 0) {
res.add(new ArrayList<Integer>(temp));
return;
}
if (target < 0) {
return;
}
for (int i = start; i < args.length; i++) {
temp.add(args[i]);
calculate(args, i, target - args[i], temp, res);
temp.remove(temp.size() - 1);
}
}
}