Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Combination sum problem using JavaScript
The combination sum problem involves finding all unique combinations from a given array where the numbers sum to a target value. Each number can be used multiple times, making this a classic backtracking problem.
Problem Statement
Given a set of candidate numbers (without duplicates) and a target number, find all unique combinations where the candidate numbers sum to the target.
Constraints:
All numbers (including target) are positive integers
The same number may be chosen multiple times
The solution set must not contain duplicate combinations
Example:
Input: candidates = [2,3,6,7], target = 7
Output: [[7], [2,2,3]]
Algorithm Approach
Since we need all possible combinations, we use backtracking with recursion rather than dynamic programming. The algorithm explores each possibility and backtracks when a path doesn't lead to a solution.
Implementation
const recursiveSum = (
candidates,
remainingSum,
finalCombinations = [],
currentCombination = [],
startFrom = 0,
) => {
if (remainingSum < 0) {
return finalCombinations;
}
if (remainingSum === 0) {
finalCombinations.push(currentCombination.slice());
return finalCombinations;
}
for (let candidateIndex = startFrom; candidateIndex < candidates.length; candidateIndex += 1) {
const currentCandidate = candidates[candidateIndex];
currentCombination.push(currentCandidate);
recursiveSum(
candidates,
remainingSum - currentCandidate,
finalCombinations,
currentCombination,
candidateIndex,
);
currentCombination.pop();
}
return finalCombinations;
}
const combinationSum = (candidates, target) => recursiveSum(candidates, target);
console.log(combinationSum([2, 3, 6, 7], 7));
console.log(combinationSum([2, 3, 5], 8));
[ [ 2, 2, 3 ], [ 7 ] ] [ [ 2, 2, 2, 2 ], [ 2, 3, 3 ], [ 3, 5 ] ]
How It Works
The algorithm uses these key concepts:
Base Cases: If remaining sum is negative, return. If zero, we found a valid combination.
Backtracking: Try each candidate, recurse, then remove it to try other possibilities.
Avoid Duplicates: The
startFromparameter ensures we don't create duplicate combinations by only considering candidates from the current index onwards.Reuse Numbers: Pass the same
candidateIndexin recursion to allow reusing the current number.
Step-by-Step Example
For candidates = [2,3,6,7], target = 7:
// Trace through the algorithm
function traceExample() {
console.log("Starting with candidates [2,3,6,7], target = 7");
console.log("1. Try 2: remaining = 5, continue with 2");
console.log("2. Try 2 again: remaining = 3, continue with 2");
console.log("3. Try 2 again: remaining = 1, continue with 2");
console.log("4. Try 2 again: remaining = -1, backtrack");
console.log("5. Try 3: remaining = 0, found combination [2,2,3]");
console.log("6. Try 7: remaining = 0, found combination [7]");
return combinationSum([2, 3, 6, 7], 7);
}
console.log("Final result:", traceExample());
Starting with candidates [2,3,6,7], target = 7 1. Try 2: remaining = 5, continue with 2 2. Try 2 again: remaining = 3, continue with 2 3. Try 2 again: remaining = 1, continue with 2 4. Try 2 again: remaining = -1, backtrack 5. Try 3: remaining = 0, found combination [2,2,3] 6. Try 7: remaining = 0, found combination [7] Final result: [ [ 2, 2, 3 ], [ 7 ] ]
Time Complexity
The time complexity is approximately O(N^(T/M)) where N is the number of candidates, T is the target value, and M is the minimal value among the candidates. This represents exploring all possible combinations.
Conclusion
The combination sum problem is solved efficiently using backtracking with recursion. The key insight is using a startFrom parameter to avoid duplicate combinations while allowing number reuse.
