synopsis · Thinking tools · chapter 8
Recursion
9 cards, about a minute. Read them the night before an interview, or right after the chapter to lock it in.
- what it is
A method that calls itself on a smaller input. Two parts: a base case that returns directly, and a recursive case that moves towards it.
- use it when
Nested or branching data (trees, folders, JSON), self-similar definitions (row n from row n − 1), and "generate all" problems.
- template
if (base) return answer;→smaller = solve(smaller input);→return combine(smaller);Then trust the smaller call. - cost
Time = calls × work per call. Space = deepest chain of calls. Chain → O(n) · halving → O(log n) · two calls on n − 1 → O(2ⁿ).
- trap
No reachable base case → frames pile up →
StackOverflowError. Java has no tail-call optimization, so depth 10⁴–10⁵ is risky. - trap
pow(x, n/2) * pow(x, n/2)makes two calls → O(n). Storehalfonce → O(log n). Same sub-problem twice = wasted work. - trap
Backtracking with a shared
StringBuilderorList: undo the change after the recursive call, or later branches see leftovers. - pro tip
Repeated sub-problems? Add a memo (
int[]filled with −1, or aHashMap) so each state is solved once. That's top-down DP. - pro tip
Too deep for the stack? Rewrite with a loop, or an explicit
ArrayDequestack that lives on the heap.
Shaky on a card? Open the chapter or flip its recall cards.