问题描述
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/ab15f2cb90d719614822514f244e35fe.png)
问题分析
- 该题与 LeetCode 77. Combinations 类似,但又有所不同,该题在组合时可以使用重复元素,然后一直 dfs 到 等于或者大于 target 为止。
- 首先画出递归树:
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/d0c43bb2c868ee5a97f73db8705d01ca.jpeg)
- 然后根据递归树设计递归函数,确定递归关系。
- 若题目不要求可能性之间的顺序,可以先对数组进行排序,这样一旦发现当前决策已经大于target,便不对后序分支进行判断以及dfs。是一种剪枝策略。
经验教训
- 先画出递归树来,一切问题都很通透,然后再设计递归函数
代码实现
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if (candidates == null || candidates.length == 0) {
return new ArrayList<>();
}
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
findcombinationSum(candidates, 0, target, new ArrayList<>(), res);
return res;
}
public void findcombinationSum(int[] candidates, int begin, int remain, ArrayList<Integer> path, List<List<Integer>> res) {
if (remain == 0) {
res.add(new ArrayList<>(path));
return;
}
for (int i = begin; i < candidates.length; ++i) {
if (remain - candidates[i] < 0) {
break;
}
path.add(candidates[i]);
findcombinationSum(candidates, i, remain - candidates[i], path, res);
path.remove(path.size() - 1);
}
return;
}
}