workshop private

← all creations

Prune

viz · created 2026-09-09

The LC 39 backtracking tree grown one call at a time — remaining-to-target in every node, the candidate taken on every edge — with the start index, the sort-and-break pruning, and copy-vs-alias recording each switchable, so duplicates, missed answers, wasted probes and a results list that ends up all empty are things you watch happen.

algorithmsinterview-prepcanvas

Combination Sum (LC 39): distinct positive candidates, a target, unlimited reuse of each candidate, every combination that hits the target exactly once. The search is a tree — each node is “what is left to reach”, each edge is the candidate just taken — and the piece draws that tree as the search enters it, one event per step: enter a node, push a candidate, record an answer (green), hit a dead end (red), skip or break, pop back up. The path the recursion is standing on is lit blue; a white ring marks the current node.

Three controls, one per classic failure.

Start index is the correctness argument. Pass i (never look left, but the same candidate may repeat) generates each multiset exactly once, in non-decreasing order. Pass 0 restarts the loop at every level, and [2, 2, 3], [2, 3, 2] and [3, 2, 2] all come out — the counter goes red with the duplicate count, and the tree is visibly wider. Pass i + 1 takes each candidate at most once, which is a different problem: the tree is small and the answers that need a repeat are simply missing.

Prune is the constant factor. With the candidates sorted, break the moment one is larger than what is left: an amber ✂ stub at the node counts the siblings that were never tested. Continue skips the oversize candidate but keeps probing its larger siblings — grey stubs, all wasted. None recurses into the negative and discovers the dead end one level down, as a red node the parent could have known not to create. The header counts nodes entered and loop probes, so the three modes are numbers, not opinions.

Record is the aliasing bug. A copy of path is the right answer. Path itself pushes a reference to the working array; the results column then shows every entry as whatever path is right now, and when the search ends and path has been popped back to empty, every answer reads []. The logic was never wrong.

Type your own candidates and target (capped so the page stays responsive — a tree past 600 nodes is truncated and says so), step through, or let it run.

Reuse

src/prune.js is a framework-free ES module:

No rendering or timers in the module; the canvas demo is reference code.

Gotchas