Classic overlapping-subproblem recursion for learning call trees.
What to inspect: Compare memoized and plain runs to see repeated subproblems collapse.
Use this page as the fast reference before opening the visualizer: what a recursive state should represent, where bugs usually come from, and which examples show each pattern clearly.
Factorial and Fibonacci are still the best first traces because the base cases are obvious and the tree shape is easy to verify.
When recursion breaks, inspect the argument tuple for each node before reading more code. Wrong state almost always explains wrong output.
Plain vs memoized traces make the cost of repeated subproblems concrete and measurable.
Four solid starting points when you want to inspect a different flavor of recursion.
Classic overlapping-subproblem recursion for learning call trees.
What to inspect: Compare memoized and plain runs to see repeated subproblems collapse.
A clean single-branch recursion that makes base cases easy to inspect.
What to inspect: Use it to verify termination, return flow, and stack depth.
A richer two-index recursion with branching and memoization value.
What to inspect: Inspect repeated states and then turn on memoization to measure savings.
A divide-and-conquer recursion where each call sharply shrinks the search space.
What to inspect: Use it to verify termination, midpoint updates, and how a recursion can stay narrow while still being efficient.
The most common failure modes in recursion traces—check these first when the output doesn't make sense.
If a stopping condition does not catch every terminating branch, recursion runs until the step limit or stack fails.
Every recursive call must move toward a smaller or simpler state. If the state does not change, the tree never converges.
Calling the recursive branch without returning or combining its value leaves parent frames with undefined or stale output.
Mutating arrays or globals across branches can hide bugs because sibling calls observe the same changing data.
Use this checklist when writing new recursive functions or reviewing a trace.
Write down exactly what each function argument means. That makes repeated states and memoization keys obvious.
Keep base cases near the top of the function and return literal, easy-to-verify answers whenever possible.
For each recursive call, confirm which argument shrinks and why that guarantees termination.
Run a plain trace first, then memoized comparison. The delta in calls and repeated subproblems often explains the algorithm faster than code alone.
Pick a template, run it with a small input, inspect the base cases, then step through one branch until the return value bubbles back up. If the tree looks repetitive, run the memoized comparison and inspect the derived insights panel for repeated subproblems and savings.