Introduction to Backtracking

This lesson defines backtracking as a systematic search technique, explains the state space tree and the choose → explore → unchoose pattern, contrasts backtracking with DP, greedy, and brute force, introduces pruning, and maps classic backtracking problems to real-world applications.

What is Backtracking?

Backtracking is an algorithmic technique for exploring all (or many) candidates for a solution by building them incrementally. When a partial solution cannot lead to a valid complete solution, the algorithm abandons that branch and returns to a previous decision point—hence “backtrack.”

Backtracking is not one fixed algorithm; it is a problem-solving paradigm built on recursion (or an explicit stack). You maintain a partial solution, try extending it, and undo the last choice when constraints fail or all extensions are exhausted.

Schematic: State space tree for [1, 2, 3] permutations

Each level picks the next element; dead ends are pruned when a choice is invalid:

                    []
           /        |        \
         [1]       [2]       [3]
        /   \     /   \       |
    [1,2] [1,3] [2,1] [2,3] [3,1] ...
      |     |     |     |     |
  [1,2,3] ...  (complete permutations at leaves)

Backtrack: if [1,2] cannot extend → undo 2, try [1,3]

Core Concepts

Every backtracking problem can be described with these building blocks:

1. State

What you track at each step: current path, board configuration, remaining choices, indices, etc.

Examples: list of chosen numbers; N×N chess board; Sudoku grid; maze cell coordinates.

2. Choices

Valid options to extend the partial solution at the current step.

Examples: unused digits; empty cells in a row; four directions in a maze.

3. Constraints

Rules that reject invalid partial solutions early.

Examples: no duplicate permutations; no two queens attack; Sudoku row/column/box uniqueness.

4. Goal / Base Case

When the partial solution is complete and should be recorded (or counted).

Examples: path length equals n; all queens placed; Sudoku grid filled.

Note: Backtracking explores a decision tree. Without pruning, it reduces to exhaustive search—but with good constraints it avoids most branches.

The Backtracking Template

The universal pattern is choose → explore → unchoose (also called pick / recurse / unpick):

def backtrack(state):
    if is_complete(state):
        record_solution(state)
        return

    for choice in valid_choices(state):
        if not is_valid(state, choice):
            continue          # prune
        apply(state, choice)  # choose
        backtrack(state)      # explore
        undo(state, choice)   # unchoose (backtrack)

For problems that need all solutions, do not return after finding one—collect every leaf. For “exists?” problems, return early on first success.

Backtracking vs DP vs Greedy vs Brute Force

All can search solution spaces, but commitments and reuse differ:

Approach Idea Remembers past work? Typical signal
Brute force Try every combination; rarely undo early No Small input; no structure to prune
Backtracking Build incrementally; abandon invalid branches Usually no table (path is implicit) “All permutations/combinations”, puzzles, constraint satisfaction
Dynamic Programming Overlapping subproblems; cache optimal counts/values Yes — memo/table “Min/max/count ways” with repeated states
Greedy One irreversible local choice per step Often O(1) Provably safe greedy choice (scheduling, ratios)

Quick Comparison Examples

Backtracking — N-Queens:

Place queen row by row; if column/diagonal conflict → backtrack
Try all valid columns per row; collect all board layouts

DP — Coin change (min coins):

Amount 6, coins [1,3,4]
dp[6] = min(dp[5]+1, dp[3]+1, dp[2]+1) — reuse sub-answers
Not generating every coin sequence explicitly

Greedy — Activity selection:

Sort by finish time; pick greedily — no undo, no full tree

Pruning Overview

Pruning skips branches that cannot yield a valid or optimal solution. It is what makes backtracking practical.

  • Constraint pruning: Invalid partial state → return immediately (Sudoku duplicate in row).
  • Feasibility pruning: Remaining slots cannot satisfy constraints (not enough cells left).
  • Bound pruning: In optimization, current cost already exceeds best known (branch-and-bound).

See Pruning techniques for a deeper dive with examples.

When to Use Backtracking

Backtracking fits when
  • You must generate or count configurations (permutations, subsets)
  • Constraints eliminate most branches (N-Queens, Sudoku)
  • Problem is constraint satisfaction on a discrete space
  • Input size is moderate with strong pruning
Consider alternatives when
  • Same sub-states repeat → use DP/memoization
  • One greedy choice is provably optimal
  • Output size is exponential and only a count is needed (may still use DP)
  • Input is too large for any tree search without heavy pruning
Interview trap: Saying “backtracking” without defining state, choices, and constraints. Always sketch the decision tree and what you prune.

Classic Backtracking Problems

These map to tutorials in this backtracking track:

1. Fundamentals

2. Board & Grid

3. Combinatorial Generation

Other Famous Backtracking Problems (reference)

  • Subset sum / partition problems
  • Graph coloring
  • Hamiltonian path
  • Knight’s tour
  • Word Break II (backtrack on top of DP reachability)

Real-Life Applications

Backtracking models systematic trial with early rejection—common in planning, puzzles, and design tools:

Backtracking family Real-world use Example
Constraint puzzlesSudoku apps, logic games, CSP solversFill 9×9 grid with pruning on rows/columns/boxes
Scheduling / assignmentExam timetables, shift rosteringAssign slots without conflicts; backtrack on clash
Routing / mazeRobot path planning, warehouse navigationExplore paths; undo at dead ends
ConfigurationHardware design, feature togglesTry valid component combinations
Chess / gamesMove generation, puzzle enginesN-Queens, eight-puzzle search
Text / patternSpell-check dictionaries on gridsWord search in Boggle-style games
CombinatoricsTest case generation, samplingAll permutations/combinations of test inputs

Cross-Domain Examples

  • Operations research: Integer programming with branch-and-bound (pruned backtracking)
  • Compilers: Parsing and code generation explore alternative productions
  • Security: Password / key search in constrained spaces
  • Bioinformatics: Sequence alignment variants explore edit paths
  • UI testing: Generate interaction sequences covering state spaces
Learn the pattern, not just the puzzle: Recognizing “generate all X under constraints” or “fill board row by row” tells you to reach for the choose-explore-unchoose template.

Key Takeaway

Backtracking = recursive search + explicit undo + prune invalid branches.

Steps to Solve Backtracking Problems

  1. Define state — What does a partial solution look like?
  2. List choices — What can you add at each step?
  3. Write constraints — When is a partial solution invalid?
  4. Identify base case — When to record or return success.
  5. Implement template — choose → recurse → unchoose.
  6. Add pruning — Reject early; avoid duplicate states if needed.
  7. Analyze complexity — Often exponential; pruning reduces practical runtime.

Next Steps

Continue Learning

  1. Pruning Techniques — Constraint, feasibility, and optimization cuts
  2. Generate Permutations — Core combinatorial backtracking
  3. N-Queens — Classic board constraint problem
  4. Dynamic Programming Intro — When overlapping subproblems replace tree search

Practice Problems

Beginner Level:

Intermediate Level:

Summary

Concept Key Points
DefinitionSystematic search with undo when partial solutions fail
PatternChoose → explore → unchoose (recursion)
PruningSkip invalid or hopeless branches early
Versus DPBacktrack explores paths; DP caches repeated optimal subproblems
ApplicationsPuzzles, permutations/combinations, grids, CSP
ComplexityOften exponential; pruning improves practical performance

Quick Reference Card

When to use backtracking:

  • ✓ Generate all permutations, combinations, or subsets
  • ✓ Constraint satisfaction (Sudoku, N-Queens)
  • ✓ Path finding in grids with undo (maze, word search)
  • ✓ Strong constraints prune most of the tree

When to prefer DP or other methods:

  • ✗ Count/min/max with overlapping states (use DP)
  • ✗ Provably greedy-optimal (use greedy)
  • ✗ Need polynomial time on large inputs without pruning

Compare with: Greedy for irreversible local choices · Dynamic Programming for cached subproblems.