Backtracking with reuse and pruning
Time Exponential in target / min(candidate) Space O(target / min) depthdfs(start, remaining): if remaining == 0 record. For i from start: if candidates[i] > remaining break (sorted); choose it and recurse with i (reuse allowed).
import java.util.*;
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> out = new ArrayList<>();
dfs(candidates, 0, target, new ArrayList<>(), out);
return out;
}
private void dfs(int[] c, int start, int remaining, List<Integer> path, List<List<Integer>> out) {
if (remaining == 0) { out.add(new ArrayList<>(path)); return; }
for (int i = start; i < c.length; i++) {
if (c[i] > remaining) break; // sorted: every later one is bigger
path.add(c[i]);
dfs(c, i, remaining - c[i], path, out);
path.remove(path.size() - 1);
}
}
}Verdict: Pruning keeps it fast for the given limits.