AlgorithmsRecursion

Recursion

A method where a function calls itself to solve smaller instances of the same problem.

Definition

Recursion is a problem-solving technique where a function calls itself to break a complex problem down into simpler subproblems. Think of a set of nested dolls: each doll contains a smaller version of itself until you reach the smallest one, the base case.

Core Concepts

Recursion has two essential pieces: the base case and the recursive case. The base case is what stops the recursion (without it, you get an infinite loop). The recursive case is where the function calls itself with a modified argument, gradually moving toward the base case.

This technique shows up in tree traversals, the Fibonacci sequence, and divide-and-conquer algorithms in general, where each recursive call peels off a smaller piece of the original problem.

How it Works

Each recursive call creates a new execution context on the call stack. The function does some work, then calls itself with a new argument that represents a smaller piece of the original problem. When the base case is finally reached, the function stops calling itself and starts returning values, unwinding the call stack in reverse order.


Think of it as descending into the layers of a problem until you hit the simplest case, then working your way back up by combining the results of each recursive call. You need a clear termination condition. Without a proper base case, recursion runs forever and overflows the stack.


Recursion often leads to clean, compact solutions, but it uses more memory because every call sits on the stack. For deep recursion, consider memoization to avoid redundant work, or convert the recursion into an iterative loop when stack depth becomes a problem.

Recursion: Step-by-Step

1. Identify the Base Case

Determine the simplest version of the problem that can be solved directly without further recursion. The base case is what stops the recursion. Without it, the function calls itself forever and overflows the stack.

2. Define the Recursive Case

Express the larger problem in terms of one or more smaller subproblems of the same shape. Each recursive call should move closer to the base case.

3. Trust the Recursion

When writing the recursive call, assume it returns the correct answer for the smaller subproblem. Combine that answer with the current step to produce the answer for the bigger problem.

4. Watch the Call Stack

Each recursive call adds a frame to the call stack. Deep recursion can cause stack overflow. Consider memoization for overlapping subproblems, or convert to iteration when depth becomes a concern.
Common Patterns

Recursion fits naturally on problems with a hierarchical structure, like tree and graph traversals, and on backtracking algorithms. Spotting when a problem can be broken into similar subproblems is most of the battle. As you solve more recursive problems, you'll start to see patterns that help you decide between a recursive and an iterative approach.

Best Practices

Recursion is one of the patterns that rewards careful planning: the base case, the recursive case, the stack budget, and any memoization. Test thoroughly so your recursive functions handle every input gracefully, including the edge cases.


Every recursive function needs a well-defined base case. Without one, the function calls itself forever and crashes the stack.

Practice Problems

Recursion clicks once you stop tracing the call stack and start trusting the recursive contract: "this function returns X for any subproblem." Work through these to internalize divide-and-conquer, recursive matching with memoization, and the recursive structure that underlies linked-list and tree problems:


Recursion
Completed
Title
Notes
Solution
Easy
Easy
Easy
Easy
Medium
Medium
Medium
Medium
Hard
Hard
Hard
Hard