This approach uses recursion and backtracking to generate all possible combinations by exploring each candidate. If a candidate is chosen, we explore further with the remaining target reduced by the candidate's value. We use backtracking to remove a candidate and try the next one. This way, we explore all possible combinations using depth-first search.
Time Complexity: O(2^T), where T is the target, as it potentially explores every combination of the candidates.
Space Complexity: O(T) for the recursion call stack and the path being explored.
1def combinationSum(candidates, target):
2 def backtrack(remaining, path, start):
3 if remaining < 0:
4 return
5 if remaining == 0:
6 result.append(list(path))
7 return
8 for i in range(start, len(candidates)):
9 path.append(candidates[i])
10 backtrack(remaining - candidates[i], path, i)
11 path.pop()
12
13 result = []
14 backtrack(target, [], 0)
15 return result
16
17candidates = [2, 3, 6, 7]
18target = 7
19print(combinationSum(candidates, target))
20
This Python implementation defines a recursive backtrack
function to explore and solve the problem by selecting candidates starting from the current index for potential reuse, stopping when the target is met or surpassed.
We can use a dynamic programming (DP) approach to solve the Combination Sum problem. We maintain a DP array where each index represents the number of ways to form that particular sum using the candidates. The approach involves iterating through candidates and updating the DP array for each possible sum that can be formed with that candidate.
Time Complexity: Roughly O(T * N), for target T and candidates N.
Space Complexity: O(T) for the dp array itself in context of storage.
1import java.util.ArrayList;
2import java.util.List;
3
4public class CombinationSumDP {
5 public static List<List<Integer>> combinationSum(int[] candidates, int target) {
6 List<List<Integer>>[] dp = new List[target + 1];
7 dp[0] = new ArrayList<>();
8 dp[0].add(new ArrayList<>());
9
10 for (int i = 1; i <= target; i++) {
11 dp[i] = new ArrayList<>();
12 for (int candidate : candidates) {
13 if (i >= candidate) {
14 for (List<Integer> combination : dp[i - candidate]) {
15 List<Integer> newComb = new ArrayList<>(combination);
16 newComb.add(candidate);
17 dp[i].add(newComb);
18 }
19 }
20 }
21 }
22
23 return dp[target];
24 }
25
26 public static void main(String[] args) {
27 int[] candidates = {2, 3, 6, 7};
28 int target = 7;
29 List<List<Integer>> results = combinationSum(candidates, target);
30 results.forEach(System.out::println);
31 }
32}
33
In the Java solution, a DP array holds lists where combinations for each target sum are stored, built step-by-step through each candidate addition and classified into dp indices by their sum value.