Skip to main content

๐Ÿ” Recursion

One-line summary: Solve a problem by breaking it into smaller instances of itself โ€” the foundation of DFS, divide-and-conquer, backtracking, and tree algorithms.


Diagramโ€‹

Recursion Overview Recursion GIF

๐ŸŽฏ Conceptโ€‹

Recursion is when a function calls itself to solve smaller instances of the same problem. Every recursive function needs:

  1. Base case โ€” the smallest input, solved directly; stops the recursion.
  2. Recursive case โ€” reduces the problem toward the base case.
  3. Trust the recursion โ€” assume the recursive call returns the correct answer (the "recursive leap of faith").

The Call Stackโ€‹

Each recursive call is pushed onto the call stack with its own local variables. When the base case returns, the frames unwind in reverse (LIFO) order.

flowchart TD
A["fact(4)"] --> B["4 * fact(3)"]
B --> C["3 * fact(2)"]
C --> D["2 * fact(1)"]
D --> E["fact(1) = 1 (base case)"]
E -.returns 1.-> D
D -.returns 2.-> C
C -.returns 6.-> B
B -.returns 24.-> A

Recursion vs Iterationโ€‹

AspectRecursionIteration
ReadabilityElegant for trees/divide-and-conquerSimpler for linear loops
MemoryO(depth) stack framesO(1) usually
RiskStack overflow on deep recursionNone
ConversionAny recursion โ†’ loop + explicit stackโ€”

Memoization (Intro)โ€‹

When recursive calls repeat the same subproblem, cache results to avoid recomputation โ€” turning exponential time into linear. This is the bridge to Dynamic Programming.


โšก Time & Space Complexityโ€‹

Recursive PatternTimeSpace (stack)
Linear (factorial)O(n)O(n)
Binary (naive Fibonacci)O(2โฟ)O(n)
Binary (memoized Fibonacci)O(n)O(n)
Divide & conquer (merge sort)O(n log n)O(log n)
Fast exponentiationO(log n)O(log n)

Key Insight: Recursion depth determines auxiliary space โ€” always bound the depth to avoid stack overflow.


Common Patternsโ€‹

Factorialโ€‹

function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}

Fibonacci (memoised)โ€‹

function fib(n, memo = {}) {
if (n <= 1) return n;
if (memo[n]) return memo[n];
return (memo[n] = fib(n - 1, memo) + fib(n - 2, memo));
}

Power (fast exponentiation)โ€‹

function power(base, exp) {
if (exp === 0) return 1;
if (exp % 2 === 0) {
const half = power(base, exp / 2);
return half * half;
}
return base * power(base, exp - 1);
}

Pitfallsโ€‹

  • Missing base case โ†’ infinite recursion / stack overflow
  • Redundant subproblem calls โ†’ add memoisation
  • Deep recursion in JS โ†’ stack size ~10k; consider iterative with explicit stack

๐Ÿงช Worked Example: Naive vs Memoized Fibonacciโ€‹

The classic demonstration of why memoization matters.

// โŒ Naive: recomputes the same subproblems exponentially
function fibNaive(n) {
if (n <= 1) return n;
return fibNaive(n - 1) + fibNaive(n - 2);
}
// Time: O(2^n) โ€” fib(40) makes ~1.6 billion calls!

// โœ… Memoized: each subproblem solved once
function fibMemo(n, memo = new Map()) {
if (n <= 1) return n;
if (memo.has(n)) return memo.get(n);
const result = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
memo.set(n, result);
return result;
}
// Time: O(n), Space: O(n)

Takeaway: The recursion tree for fibNaive(5) computes fib(2) three times and fib(1) five times. Memoization prunes those repeats โ€” the same idea that powers Dynamic Programming.


Practice Problemsโ€‹

ProblemDifficultySolution
LC 231 โ€” Power of TwoEasy
LC 110 โ€” Balanced Binary TreeEasy
LC 24 โ€” Swap Nodes in PairsMedium
LC 344 โ€” Reverse StringEasy
LC 509 โ€” Fibonacci NumberEasy
LC 326 โ€” Power of ThreeEasy
LC 779 โ€” K-th Symbol in GrammarMedium
LC 95 โ€” Unique Binary Search Trees IIMedium
LC 894 โ€” All Possible Full Binary TreesMedium
CC โ€” Recamรกn Sequence (RECAMAN)Easy
LC 241 โ€” Different Ways to Add ParenthesesMedium
LC 21 โ€” Merge Two Sorted ListsEasy
LC 50 โ€” Pow(x, n)Medium
LC 70 โ€” Climbing StairsEasy
LC 104 โ€” Maximum Depth of Binary TreeEasy
LC 111 โ€” Minimum Depth of Binary TreeEasy
LC 206 โ€” Reverse Linked ListEasy
LC 226 โ€” Invert Binary TreeEasy
LC 234 โ€” Palindrome Linked ListEasy
LC 342 โ€” Power of FourEasy
LC 372 โ€” Super PowMedium
LC 390 โ€” Elimination GameMedium
LC 486 โ€” Predict the WinnerMedium
LC 687 โ€” Longest Univalue PathMedium
LC 698 โ€” Partition to K Equal Sum SubsetsMedium
LC 700 โ€” Search in a Binary Search TreeEasy
LC 701 โ€” Insert into a Binary Search TreeMedium
LC 1137 โ€” N-th Tribonacci NumberEasy
LC 1342 โ€” Number of Steps to Reduce to ZeroEasy
LC 1545 โ€” Find Kth Bit in Nth Binary StringMedium
CC โ€” Factorial (FACT)Easy
CC โ€” Tower of Hanoi (HANOI)Medium
CC โ€” Recursive Function (RECFUNC)Easy

โ† Back to Home ยท ยฉ sparshjaswal