题目
Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order.
The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.
Example 1:
Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.
Example 2:
Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]
Example 3:
Input: candidates = [2], target = 1
Output: []
Example 4:
Input: candidates = [1], target = 1
Output: [[1]]
Example 5:
Input: candidates = [1], target = 2
Output: [[1,1]]
Constraints:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
All elements of candidates are distinct.
1 <= target <= 500
思路
使用DFS,当前路径上的点记录在List<Integer> curr
中,int start
记录加入curr的下个元素的范围是从candidates[start]
至candidates[candidates.length - 1]
,加入一个元素后将targer
减去这个元素的值。当target等于0时,curr为一个成立的答案;小于0时说明最后加入的元素太大了,直接return回退至上一级。
代码
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new LinkedList<>();
if (candidates == null || candidates.length == 0) return res;
dfs(candidates, target, 0, new LinkedList<>(), res);
return res;
}
public void dfs(int[] candidates, int target, int start, List<Integer> curr, List<List<Integer>> res) {
if (target < 0) return;
if (target == 0) res.add(new LinkedList<>(curr));
for (int i = start; i < candidates.length; i++) {
curr.add(candidates[i]);
dfs(candidates, target - candidates[i], i, curr, res);
curr.remove(curr.size() - 1);
}
}
}
考虑到有些情况一定不成立可以提前截至,先对candidates进行排序,在dfs中遍历添加下一个元素时,如果加入下个元素已经会超过target值了,candidates在该元素后面的元素又更大,所以都不成立,直接break。修改如下。
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new LinkedList<>();
if (candidates == null || candidates.length == 0) return res;
Arrays.sort(candidates);
dfs(candidates, target, 0, new LinkedList<>(), res);
return res;
}
public void dfs(int[] candidates, int target, int start, List<Integer> curr, List<List<Integer>> res) {
// if (target < 0) return;
if (target == 0) res.add(new LinkedList<>(curr));
for (int i = start; i < candidates.length; i++) {
if (target < candidates[i]) break;
curr.add(candidates[i]);
dfs(candidates, target - candidates[i], i, curr, res);
curr.remove(curr.size() - 1);
}
}
}