mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-15 00:21:17 +08:00
66 lines
2.0 KiB
JavaScript
66 lines
2.0 KiB
JavaScript
/**
|
|
* @param {number[]} candidates - candidate numbers we're picking from.
|
|
* @param {number} remainingSum - remaining sum after adding candidates to currentCombination.
|
|
* @param {number[][]} finalCombinations - resulting list of combinations.
|
|
* @param {number[]} currentCombination - currently explored candidates.
|
|
* @param {number} startFrom - index of the candidate to start further exploration from.
|
|
* @return {number[][]}
|
|
*/
|
|
function combinationSumRecursive(
|
|
candidates,
|
|
remainingSum,
|
|
finalCombinations = [],
|
|
currentCombination = [],
|
|
startFrom = 0,
|
|
) {
|
|
if (remainingSum < 0) {
|
|
// By adding another candidate we've gone below zero.
|
|
// This would mean that the last candidate was not acceptable.
|
|
return finalCombinations;
|
|
}
|
|
|
|
if (remainingSum === 0) {
|
|
// If after adding the previous candidate our remaining sum
|
|
// became zero - we need to save the current combination since it is one
|
|
// of the answers we're looking for.
|
|
finalCombinations.push(currentCombination.slice());
|
|
|
|
return finalCombinations;
|
|
}
|
|
|
|
// If we haven't reached zero yet let's continue to add all
|
|
// possible candidates that are left.
|
|
for (let candidateIndex = startFrom; candidateIndex < candidates.length; candidateIndex += 1) {
|
|
const currentCandidate = candidates[candidateIndex];
|
|
|
|
// Let's try to add another candidate.
|
|
currentCombination.push(currentCandidate);
|
|
|
|
// Explore further option with current candidate being added.
|
|
combinationSumRecursive(
|
|
candidates,
|
|
remainingSum - currentCandidate,
|
|
finalCombinations,
|
|
currentCombination,
|
|
candidateIndex,
|
|
);
|
|
|
|
// BACKTRACKING.
|
|
// Let's get back, exclude current candidate and try another ones later.
|
|
currentCombination.pop();
|
|
}
|
|
|
|
return finalCombinations;
|
|
}
|
|
|
|
/**
|
|
* Backtracking algorithm of finding all possible combination for specific sum.
|
|
*
|
|
* @param {number[]} candidates
|
|
* @param {number} target
|
|
* @return {number[][]}
|
|
*/
|
|
export default function combinationSum(candidates, target) {
|
|
return combinationSumRecursive(candidates, target);
|
|
}
|