多变量的递归2-组合总和问题(每个数字可以使用多次)
问题描述:给定一个无重复元素的数组和一个目标数,找出所有数组中数字和为目标的组合 (数组中的数字可以重复使用)。
/**
* problem
* an array Arr with no repeated numbers, you can fetch numbers from the array,
* and one number can be fetched one or more times, with these numbers their sum
* is a given numbers which is hold by target
* example 1
* int [] candidates = {3 ,5 ,7 , 9, 11, 14}
* target number 20
* all possibilities
* 3+3+3+3+3+5
* 3+3+3+11
* 3+3+7+7
* 3+3+14
* 3+5+5+7
* 5+5+5+5
* 9+11
*/
import java.util.*;
public class CombinationSum {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
backtrack(candidates, target, 0, new ArrayList<>(), 0, res);
return res;
}
private void backtrack(int[] candidates, int target, int start, List<Integer> path, int sum, List<List<Integer>> res) {
// 终止条件:当前和等于目标值
if (sum == target) {
res.add(new ArrayList<>(path));
return;
}
// 终止条件:当前和超过目标值
if (sum > target) {
return;
}
// 遍历所有可能的选择
for (int i = start; i < candidates.length; i++) {
// 做出选择
path.add(candidates[i]);
backtrack(candidates, target, i, path, sum + candidates[i], res); // 注意这里start仍然是i,因为可以重复使用
// 撤销选择
path.remove(path.size() - 1);
}
}
}
注意代码中 res.add(new ArrayList<>(path)); 为什么不是res.add(path);
因为path再遍历的过程中会变化的
如果res.add(path)的话,只可能加到最终的一个数据,请思考一下最终的数据是一个合法的答案,还是其他什么呢?是否都是空
但是如果new ArrayList<>(path) 就可以把当前满足条件的列表做一个快照固定下来
浙公网安备 33010602011771号