题目分析
- 排序可以保证选择的数字,当超过remain时,一定凑不出,可以提前结束
- dfs的退出条件显然为凑够target
Solution
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if (candidates == null || candidates.length == 0)
return null;
List<List<Integer>> list = new ArrayList<>();
List<Integer> nums = new ArrayList<>();
// 保证数字是从小到大选择的
Arrays.sort(candidates);
dfs(0, target, candidates, nums, list);
return list;
}
/**
* @param begin 从哪个位置开始选择
* @param remain 还需要多少凑过target
*/
private void dfs(int begin, int remain, int[] candidates, List<Integer> nums, List<List<Integer>> list) {
if (remain == 0) {
list.add(new ArrayList<>(nums));
return;
}
for (int i = begin; i < candidates.length; i++) {
// 由于有序,当第i个大于remain时不能选了,后面的一定不能选
if (remain < candidates[i])
return;
nums.add(candidates[i]);
// candidates 中的数字可以无限制重复选取,所以下一次还是从i开始选择
dfs(i, remain - candidates[i], candidates, nums, list);
nums.remove(nums.size() - 1);
}
}
}
Reference:小码哥MJ