interviewpath
  • 0day streak
  • 10total XP
  • Level 1
0/6

Unit 1 · Algorithms · Lesson 11 of 24

Recursion and backtracking

Recursion solves a problem by trusting the solution to smaller instances, and backtracking applies it to search: build a candidate one choice at a time and undo choices that cannot lead to a valid answer. Interviewers use these problems to check how you define state, choices and base cases, and how you bound the size of the search.
About 5 hFocus mode

Step 1: Learn the ideas

  • Recursive contracts, base cases and induction
  • Recursion trees and the cost of recursive calls
  • Decision trees: include/exclude versus choose-next
  • Subsets, combinations and permutations
  • Duplicate handling with sorting and sibling skipping
  • Pruning with constraints and bounds
  • Grid search with temporary marking
  • Copying the current path versus sharing it
  • Recursion depth limits and explicit stacks
  • From backtracking to memoization

Why it matters

Many problems are naturally recursive: trees, nested structures, divide and conquer, and every "generate all valid configurations" task. Writing recursion well means specifying exactly what a call returns and then trusting it for smaller inputs. Backtracking is recursion over a tree of decisions with undo; it is how constraint solvers, parsers and search procedures work. In interviews it tests clarity about state and honest complexity analysis, since the output itself is often exponential.

Core ideas

Recursion as induction. Write the contract first, for example "height(node) returns the number of nodes on the longest downward path from node, and 0 for an empty tree". Handle the base case, then assume the contract holds for smaller inputs. Correctness is an induction on input size; termination needs every call to move toward a base case. MIT 6.006 classifies recursive algorithms by the shape of their call graph: a star for brute force, a chain for decrease and conquer, a tree for divide and conquer, and a DAG with shared subproblems for dynamic programming.

Cost. Draw the recursion tree and add up the work in its nodes. Space is the maximum depth times the frame size, plus anything else allocated. Passing copies (path + [x], string slices) adds O(length) per call; sharing one mutable path and undoing changes avoids that.

Pattern: Backtracking search.

def backtrack(state):
    if is_complete(state):
        record(copy_of(state))
        return
    for choice in choices(state):
        if not feasible(state, choice):
            continue                 # prune
        apply(choice, state)
        backtrack(state)
        undo(choice, state)

Invariant: state is identical on entry and exit; only the recursive call sees the applied choice. The two classic bugs are forgetting to undo and recording a reference to the mutable path instead of a copy. In Go, appending to a shared slice can also overwrite results you already stored.

Decision-tree shapes.

  • Subsets: at index i, include or exclude a[i]; 2ⁿ leaves, and copying each subset makes it O(n × 2ⁿ).
  • Combinations and combination sums: choose the next element from index start onward so each set appears once in a canonical order; recurse with i when reuse is allowed and i + 1 when it is not.
  • Permutations: choose any unused element; n! leaves, O(n × n!) with copying.
  • Duplicate values: sort first, then at the same depth skip a value equal to its previous sibling (i > start and a[i] == a[i - 1]).

Pruning. Cut branches that cannot succeed: stop when the remaining target goes negative (with sorted positive candidates you can break out of the loop), track used columns and diagonals in N-Queens, or add a closing parenthesis only while one is still open. Pruning rarely improves the worst-case bound, but it can shrink the explored tree dramatically.

Grids. For path search in a grid (Word Search), mark a cell as visited before recursing and restore it afterwards, so one path never reuses a cell while other paths still can.

When it becomes dynamic programming. If the same subproblem (say, the same remaining index and remaining target) recurs and its answer does not depend on how you reached it, memoize it. If the task is to list every configuration, memoization helps little: the output size is the cost.

Common misconceptions

  • "Recursion is risky, so avoid it." It is often the clearest correct solution; know the depth and your language's limit, and convert to an explicit stack when depth can reach tens of thousands.
  • "Backtracking is O(2ⁿ)." State the bound from the decision tree and the output, for example O(n × 2ⁿ) for subsets or O(n × n!) for permutations; copying counts.
  • "Recording the current path is enough." Record a copy; the shared path keeps changing as the search continues.
  • "A global visited set prevents duplicate outputs." Duplicates caused by repeated input values need sorting and sibling skipping; a global visited set can wrongly block valid paths.
  • "Pruning improves the worst case." Usually it improves typical behavior only; say so when asked.

How to approach it

Before coding, name the state, the choices at each step, the completion test and the pruning rule. Draw the first two levels of the decision tree for a tiny input and count leaves to get the bound. Test an empty input and an input with duplicates. Interviewers typically probe the complexity of exponential outputs, duplicate handling and whether memoization applies. Practicing the template on varied problems transfers to new ones; memorizing particular question lists does not.

Suggested order

  1. 1Read Chapter 1 (Recursion) of Jeff Erickson’s Algorithms, especially the sections on reductions, simplify and delegate, and recursion trees.
  2. 2Read MIT 6.006 Lecture 15 (Recursive Algorithms) for the classification of recursive algorithms by call-graph shape and the SRT BOT framework.
  3. 3Read Chapter 2 (Backtracking) of Erickson’s Algorithms, focusing on N Queens, Subset Sum and The General Pattern.
  4. 4Solve Subsets and Permutations with the choose, recurse, undo template and state the O(n · 2^n) and O(n · n!) bounds.
  5. 5Solve Combination Sum, then Subsets II and Combination Sum II to practice the start index and sibling skipping.
  6. 6Solve Letter Combinations of a Phone Number and Generate Parentheses, pruning invalid prefixes early.
  7. 7Solve Word Search with temporary marking, then Palindrome Partitioning and N-Queens as harder review problems.

Step 2: Check off what you can do

Tap each one you can genuinely do or explain. Each earns 10 XP.

Step 3: Go deeper

  • Algorithms (Jeff Erickson): Recursion and Backtracking chapters, with amortized-analysis notesStart here

    Jeff Erickson, University of Illinois Urbana-Champaign

    Section: Ch. 1: Recursion

    Recursion as reduction to smaller instances, and analyzing it with recursion trees.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Algorithms (Jeff Erickson): Recursion and Backtracking chapters, with amortized-analysis notesStart here

    Jeff Erickson, University of Illinois Urbana-Champaign

    Section: Ch. 2: Backtracking

    N Queens, subset sum and the general backtracking pattern, with careful running-time analysis.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • MIT 6.006 Introduction to Algorithms (Spring 2020)

    MIT OpenCourseWare

    Section: Lecture 15: Recursive Algorithms (Dynamic Programming, Part 1)

    The SRT BOT framework and the classification of recursive algorithms (brute force, decrease and conquer, divide and conquer, dynamic programming) by call-graph shape.

    Open(opens in a new tab)Link responded, 5 Oct 2026
  • Competitive Programmer’s Handbook: search, amortized-analysis, range-query and trie sections

    CSES

    Section: Ch. 5: Complete search

    Generating subsets and permutations, backtracking and pruning, in compact code.

    Open(opens in a new tab)Link responded, 5 Oct 2026

Step 4: Practice

For every problem, write the state, the choices, the completion test and the pruning rule before coding, and draw the first two levels of the decision tree. Always record a copy of the current path. Subsets II and Combination Sum II are the duplicate-handling checks, Word Search checks marking and restoring, and Palindrome Partitioning and N-Queens are review problems for cut-position search and constraint pruning.

Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).

Step 5: Test yourself

Answer each one out loud or on paper before you finish the lesson.

  1. Question 1What is the precise contract of your recursive function, and what is its base case?
  2. Question 2Why must you record a copy of the path rather than the path itself?
  3. Question 3How does a start index prevent duplicate combinations, and how does sibling skipping handle duplicate values?
  4. Question 4What is the honest time bound for generating all permutations, including output?
  5. Question 5What does pruning change about the worst case, and what does it not change?
  6. Question 6When does a recursive search have overlapping subproblems worth memoizing?

You’re done when you can

  • Write subset, permutation and combination generators from memory, with correct bounds, in under 10 minutes each.
  • Solve one unseen backtracking problem with duplicate inputs in under 30 minutes without producing duplicate outputs.
  • Explain the recursion-depth limit of your language and convert one recursive solution to an explicit stack.
  • Say, for a given recursive search, whether memoization would help and why.

Finish the lesson

How confident do you feel?

Lesson complete!

+50 XP

Reviews will come up on the Practice tab so it sticks.

Unlocks next: Trees and binary search trees, Graph traversal: BFS, DFS and components, Divide and conquer, Dynamic programming foundations

Your notes and study time

Log study time