CMD Guide
HomeDSARecursion

Recursive Algorithm Strategies

A recursive algorithm strategy is a family of trade-offs about when to split a problem, whether subproblems overlap, and whether a previously computed answer can be reused instead of recomputed — the choice of strategy (divide & conquer, dynamic programming, backtracking, greedy-recursion) follows directly from answering those three questions before you write a single line of code.

Recognize the pattern

Brute force vs optimal

Take Fibonacci as the running example because it cleanly exposes the difference between divide & conquer applied naively and dynamic programming.

Brute-force recursion (naive divide & conquer, no reuse): fib(n) = fib(n-1) + fib(n-2). Each call spawns two more, and fib(n-2) is recomputed independently inside both the fib(n-1) branch and directly — the subproblems overlap but nothing remembers that. Cost: exponential time, O(n) space (call stack depth).

Optimal (DP): cache each fib(k) the first time it is computed; every later request for fib(k) is an O(1) lookup. Cost: linear time, O(n) space (cache + stack, or O(1) with iterative bottom-up).

Complexity, derived

Brute force: let T(n) be the number of calls to compute fib(n). T(n) = T(n-1) + T(n-2) + 1, same recurrence shape as Fibonacci itself, so T(n) grows as φn where φ ≈ 1.618 → O(φn) time, O(n) space for the deepest call stack.

Memoized DP: there are only n+1 distinct subproblems (fib(0)..fib(n)); each is computed exactly once doing O(1) work beyond its two recursive lookups → O(n) time, O(n) space (memo table + recursion stack).

General divide & conquer recurrence (non-overlapping subproblems, e.g. merge sort): T(n) = a·T(n/b) + f(n). By the Master Theorem, if f(n) = O(nlogba), T(n) = O(nlogba log n). Merge sort: a=2, b=2, f(n)=O(n) → T(n) = O(n log n), space O(n) for merge buffers + O(log n) stack. Binary search is the degenerate case with a=1: T(n) = T(n/2) + O(1) → Θ(log n) — divide & conquer where one half is discarded instead of solved.

Traced worked example: fib(5)

CallBrute force: times evaluatedMemoized: computed or lookup?
fib(5)1computed
fib(4)1computed
fib(3)2computed once, then lookup
fib(2)3computed once, then lookup ×2
fib(1)5base case, lookup after first
fib(0)3base case, lookup after first

Brute force makes 15 total calls for n=5 (growing exponentially); memoized DP makes exactly 6 distinct computations plus O(1) lookups for every repeat request.

Java: brute force vs memoized vs bottom-up

class Fib {
    // Brute force divide & conquer: O(phi^n) time, O(n) space
    static long fibBrute(int n) {
        if (n <= 1) return n;
        return fibBrute(n - 1) + fibBrute(n - 2);
    }

    // Top-down DP (memoized recursion): O(n) time, O(n) space
    // Entry point: the memo MUST be seeded with -1. A bare new long[n+1]
    // defaults to 0, so the guard below would treat every slot as "already
    // computed" and silently return 0 for all n >= 2.
    static long fib(int n) {
        long[] memo = new long[n + 1];
        java.util.Arrays.fill(memo, -1);   // -1 = "not computed yet"
        return fibMemo(n, memo);
    }

    static long fibMemo(int n, long[] memo) {
        if (n <= 1) return n;
        if (memo[n] != -1) return memo[n];
        memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
        return memo[n];
    }

    // Bottom-up DP (tabulation, no recursion): O(n) time, O(1) space
    static long fibIter(int n) {
        if (n <= 1) return n;
        long prev2 = 0, prev1 = 1;
        for (int i = 2; i <= n; i++) {
            long cur = prev1 + prev2;
            prev2 = prev1;
            prev1 = cur;
        }
        return prev1;
    }
}

Pitfalls

When to use / when not, vs alternatives

StrategyUse whenAvoid whenNamed alternative
Divide & conquersubproblems independent, combine step is cheapsubproblems overlap heavily (redundant work)Dynamic programming
Dynamic programmingoverlapping subproblems, optimal substructureno repeated subproblems, or state space too large to storeDivide & conquer / greedy
Backtrackingneed all/feasible solutions, constraints prune earlyproblem has a known greedy or DP closed form (backtracking wastes time)DP (if optimal substructure exists) or greedy
Greedy recursionlocal optimal choice provably yields global optimumgreedy-choice property unproven (may give wrong answer)Dynamic programming (guarantees correctness by exploring all choices)

Takeaways

Recall: Why does naive recursive Fibonacci take exponential time while the recursion for merge sort (also two recursive calls) takes only O(n log n)?


Sources: CLRS (Cormen, Leiserson, Rivest, Stein), Introduction to Algorithms, ch. 4 & 15; original page content on recursive algorithm strategies.

🤖 Don't fully get this? Learn it with Claude

Stuck on Recursive Algorithm Strategies? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Recursive Algorithm Strategies** (DSA) and want to truly understand it. Explain Recursive Algorithm Strategies from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Recursive Algorithm Strategies** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Recursive Algorithm Strategies** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Recursive Algorithm Strategies** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes