Latticework

Command Palette

Search for a command to run...

Algorithms

Recursion

16 min

Explanation

A recursive function calls itself on a smaller version of the problem, until it hits a base case simple enough to answer directly. Every recursive function needs both pieces:

def factorial(n):
    if n == 0:          # base case — stops the recursion
        return 1
    return n * factorial(n - 1)   # recursive case — smaller subproblem

Each call to factorial waits on a "call stack" for the call below it to return — that's the same stack data structure from the previous course. Forget the base case, and you recurse forever until Python raises a RecursionError.

Try it

Correct, but exponentially slow — fib(30) alone makes over a million calls, because fib(28) gets recomputed from scratch many times over.

Loading editor…
Explanation

Naive recursive Fibonacci is O(2ⁿ) because it re-solves the same subproblems repeatedly. Memoization — caching results you've already computed — turns it into O(n):

def fib_memo(n, memo=None):
    if memo is None:
        memo = {}
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fib_memo(n - 1, memo) + fib_memo(n - 2, memo)
    return memo[n]

This is your first taste of dynamic programming: recursion plus a cache of subproblem results, so no subproblem is ever solved twice.

Exercise

Write a function `factorial(n)` that computes n! recursively (n * (n-1) * ... * 1, with `factorial(0) == 1`).

Exercise

Write a function `fib_memo(n, memo=None)` that returns the nth Fibonacci number (0-indexed: fib(0)=0, fib(1)=1) using recursion WITH memoization, so repeated calls don't redo work.

Quiz

What happens if a recursive function is missing a proper base case?

Checkpoint

You can write a recursive function with a correct base case, and add memoization to avoid redundant recursive work.