Backtracking

Recursion Family

Signal

Generate all subsets/permutations/combinations

Template

Choose, recurse, un-choose; prune early.

Worked example (1)

#16

Backtracking

Backtracking

Given distinct positive candidates and a target, return all unique combinations that sum to the target. A number may be reused unlimited times.

function combinationSum(candidates: number[], target: number): number[][] {
  const res: number[][] = [];
  const path: number[] = [];
  const backtrack = (start: number, remaining: number): void => {
    if (remaining === 0) { res.push([...path]); return; }
    if (remaining < 0) return;
    for (let i = start; i < candidates.length; i++) {
      path.push(candidates[i]);
      backtrack(i, remaining - candidates[i]); // i, not i+1: reuse allowed
      path.pop();
    }
  };
  backtrack(0, target);
  return res;
}
Insight

Passing i (not i + 1) permits reuse; starting at start avoids duplicate combinations.