Catalan numbers are one of the most famous sequences in combinatorics: 1, 1, 2, 5, 14, 42, … They count a surprising number of things — the number of binary search trees you can build from n nodes, the number of ways to balance n pairs of parentheses, the number of ways to triangulate a polygon, and many more. This problem asks you to compute the nth one.
Problem. Given an integer n, return the nth Catalan number Cn. The sequence is defined by
C0 = 1 and the recurrence C[k] = sum over i from 0 to k-1 of C[i] * C[k-1-i].
Example: n = 4 → answer 14 (the values are C0=1, C1=1, C2=2, C3=5, C4=14).
The slow way first
The textbook definition is recursive: to get C[k], sum C[i] * C[k-1-i] over every split point i. Translated directly into a recursive function with no memo, that recomputes the same smaller Catalan numbers over and over — the call tree explodes exponentially, the same trap as naive Fibonacci.
The question to ask: which smaller values does C[k] depend on? Only C0 through C[k-1]. So if I compute them in order and store each one, every term I need is already sitting in a table.
The idea: build the table bottom-up
Make an array dp where dp[k] will hold C[k]. Seed dp[0] = 1. Then fill dp[1], dp[2], … in order. For each k, walk a split index i from 0 to k-1 and add dp[i] * dp[k-1-i] to a running total. The two factors are a symmetric pair: as i moves right from the front, k-1-i moves left from the back, and they sweep toward the middle.
The key insight: every C[k] is a sum over all the ways to split into a left part of size i and a right part of size k-1-i. That is exactly why Catalan numbers count binary search trees — pick a root, and the left and right subtrees are independent smaller problems.
Walk through it
Step through the animation. The cells hold C0..C4. We build C3 term by term: the i pointer marks the left factor and the k-1-i pointer marks its symmetric partner. The first and last terms mirror each other (C0*C2 and C2*C0), and the middle term C1*C1 is where the two pointers meet. The three products 2 + 1 + 2 sum to 5, so C3 = 5. Then C4 fills the same way to 14.
Pseudocode
dp = array of zeros, length n + 1
dp[0] = 1
for k from 1 to n:
total = 0
for i from 0 to k - 1:
total += dp[i] * dp[k - 1 - i] # symmetric pair
dp[k] = total
return dp[n]The Python solution
def catalan(n):
dp = [0] * (n + 1)
dp[0] = 1
for k in range(1, n + 1):
total = 0
for i in range(k):
total += dp[i] * dp[k - 1 - i]
dp[k] = total
return dp[n]dpis the table;dp[k]ends up holding the kth Catalan number.dp[0] = 1is the only base case the recurrence needs.- The outer loop fills
dp[1],dp[2], … in order, so every value an inner term reads is already computed. - Line 7 is the heart of it:
dp[i] * dp[k - 1 - i]multiplies a left factor by its symmetric partner, andrange(k)sweeps the split point across all positions. - After the inner loop,
totalis the full sum — store it asdp[k]and move on.
Complexity
| Case | Time | Notes |
|---|---|---|
| Naive recursion (no memo) | exponential (moderate) | recomputes the same subproblems |
| Bottom-up DP (this solution) | O(n²) (slow) | n values, each an O(n) inner sum |
O(n) (moderate)The inner loop does up to k multiplications for each k, so the total work is 1 + 2 + … + n, which is O(n²). We store one value per index, giving O(n) space. (There is also a closed form Cn = (2n)! / ((n+1)! * n!), but the DP is the version interviewers want to see derived.)
When this pattern shows up
Whenever a count splits into "pick a center, then an independent left subproblem and right subproblem," you are looking at a Catalan-style recurrence: sum over the split point of (left ways) * (right ways). Unique BSTs, balanced parentheses, valid mountain/ballot sequences, and polygon triangulations are all this same move.
Mind the index in the partner: it is dp[k - 1 - i], not dp[k - i]. The -1 is because the recurrence
splits k items into a left part of size i and a right part of size k - 1 - i, with one item acting as
the center. An off-by-one here silently produces wrong (but plausible) numbers.
Practice
Using the table C0=1, C1=1, C2=2, C3=5, what is C4? Sum the symmetric products.
1. Why is the bottom-up DP O(n²) instead of exponential?
2. In the term dp[i] * dp[k - 1 - i], what is dp[k - 1 - i]?
3. Which famous count does the nth Catalan number give?
4. What is the extra space used by this solution?