roadmap/Backtracking

Topic 9 / 16

Backtracking

HardRecursion~5 days
Challenging
progress0 / 13 solved

Build candidates incrementally and abandon ('backtrack') when a constraint is violated.

โš ๏ธ
Why this topic is hard

Backtracking is hard because the solution isn't a sequence of independent decisions โ€” each choice constrains future choices. The recursive structure looks simple but visualizing the full decision tree takes practice. The most common mistake is not properly undoing state changes before trying the next branch โ€” this is the literal 'back' in backtracking.

Build a solution incrementally. At each step, try all valid choices. If a choice leads to an invalid state or dead end, undo it ('backtrack') and try the next choice. The search space is a decision tree โ€” backtracking prunes branches early to avoid exploring invalid paths.

  • โ—†Generate all combinations, permutations, or subsets
  • โ—†Constraint satisfaction (Sudoku, N-Queens)
  • โ—†Word search in a grid
  • โ—†Maze / path finding with constraints
Subsets
At each index, choose to include or exclude. Recurse with i+1.
Combinations
Pick k elements from n. Branch on each remaining element.
Permutations
Pick from remaining elements. Use a visited set.
Constraint propagation
Check validity at each step to prune early (Sudoku, N-Queens).
Backtracking
Generate All Subsets
RECORD
current path (depth = 0)
[empty]
subsets found so far (1 / 8)
[โˆ…]
Record subset: [โˆ…]
Empty set is always a valid subset.
The "back" in backtracking: path.pop() undoes the last choice. Without this, you'd have no way to explore alternative branches.
step 1/23
Brute force
Generate all possible sequences (iteratively) โ€” exponential without pruning.
Observation
Many paths share a prefix. Once a prefix is invalid, all paths with that prefix can be pruned.
Optimization
DFS with a `path` array. Push candidate, recurse, pop (backtrack). Add validity check at each step.
Final complexity
O(n ร— 2โฟ) for subsets, O(n ร— n!) for permutations โ€” inherently exponential but pruning reduces constant factor.

What must you do after each recursive call in a backtracking solution?

How do you avoid duplicate subsets when the input has duplicate numbers?

In Combination Sum, why can you reuse the same index i in the recursive call?

Check each question you can answer confidently before moving to the next topic.

Progress is saved on this device