Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[2,3,6,7],
target =7
, A solution set is: [ [7], [2,2,3] ]
Example 2:
Input: candidates = [2,3,5],
target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
backtracking
每次递归到某个元素的时候,tmp中加入当前元素,target减去当前元素,当target=0的时候,把tmp加入res中
剪枝:排序+递归过程中判断当前元素是否大于target (大于就break)
s = target / min(nums[i]), T = C(s, 1) + C(s, 2) + ... + C(s, s) = 2^s -> O(2^s)
time: O(2^s), space: O( target / min(nums[i]) )
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(candidates); backtracking(candidates, target, 0, new ArrayList<>(), res); return res; } private void backtracking(int[] candidates, int target, int idx, List<Integer> tmp, List<List<Integer>> res) { if(target == 0) res.add(new ArrayList<>(tmp)); for(int i = idx; i < candidates.length; i++) { if(candidates[i] > target) break; tmp.add(candidates[i]); backtracking(candidates, target - candidates[i], i, tmp, res); tmp.remove(tmp.size() - 1); } } }
or
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(candidates); dfs(candidates, 0, target, new ArrayList<>(), res); return res; } public void dfs(int[] candidates, int idx, int target, List<Integer> list, List<List<Integer>> res) { if(idx == candidates.length) { if(target == 0) { res.add(new ArrayList<>(list)); } return; } for(int i = 0; i <= target / candidates[idx]; i++) { for(int j = 0; j < i; j++) { list.add(candidates[idx]); } dfs(candidates, idx + 1, target - i * candidates[idx], list, res); for(int j = 0; j < i; j++) { list.remove(list.size() - 1); } } } }