Web Analytics

๐Ÿ”ฌ Analyzing Recursive Algorithms

Beginner Friendly ~20 min read

You know merge sort is fast - but exactly HOW fast? In this lesson, you'll learn a simple visual method to analyze recursive algorithms, plus a powerful shortcut called the Master Theorem that works like magic!

This builds on your complexity intuition from the previous lesson.

๐Ÿ’ผ The Google Interview Question

Interviewer: "Explain why merge sort is O(n log n)."

Candidate A: "Um... because it's a divide-and-conquer algorithm?" โŒ
Result: Rejected. No proof.

Candidate B: "Let me draw the recursion tree..." โœ…
Draws tree, counts levels, shows work at each level.
Interviewer: "Perfect! When can you start?"

The difference? Candidate B could prove it, not just memorize it.

Merge Sort Recursion Tree (n=8)

n = 8 Work: O(n) Level 0: 1 ร— n = n n/2 = 4 Work: O(n/2) n/2 = 4 Work: O(n/2) Level 1: 2 ร— n/2 = n n/4 = 2 O(n/4) n/4 = 2 O(n/4) n/4 = 2 O(n/4) n/4 = 2 O(n/4) Level 2: 4 ร— n/4 = n โ‹ฎ 1 1 1 ... 1 1 Level log n: n ร— 1 = n Total: log n levels ร— n work per level = O(n log n) โœ… This is why merge sort is O(n log n)!
๐Ÿ“Š Pattern

Every level does n work total

๐Ÿ“ Depth

Tree has log n levels

๐ŸŽฏ Result

n ร— log n = O(n log n)

The recursion tree method: Draw it, count the levels, sum the work. That's it!

The Challenge: Analyzing Merge Sort

Let's say you're in a job interview and someone asks: "What's the time complexity of merge sort?"

You might say "O(n log n)" - but then they ask: "How do you KNOW that?"

๐Ÿค” The Problem

With loops, you can count iterations. But merge sort calls itself recursively - how do you count that?

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])    # โ† Recursive call
    right = merge_sort(arr[mid:])   # โ† Recursive call
    return merge(left, right)       # โ† Some work here

Question: How many operations does this do for an array of size n?

Step 1: Draw the Recursion Tree

The best way to understand recursive algorithms is to draw how they break down the problem. Watch this visualization:

๐Ÿ’ก What You're Seeing

Merge sort breaks the problem into smaller pieces:

  • Level 0: Sort array of size n
  • Level 1: Sort 2 arrays of size n/2
  • Level 2: Sort 4 arrays of size n/4
  • Level 3: Sort 8 arrays of size n/8
  • ...and so on until arrays are size 1

Counting Operations by Hand

Let's count the work at each level for an array of size 8:

Level Number of Arrays Size of Each Work Per Array Total Work
0 1 8 8 8
1 2 4 4 8
2 4 2 2 8
3 8 1 1 8
Pattern Discovered! Each level does exactly n work (8 in this case).
How many levels? logโ‚‚(n) levels (because you keep dividing by 2).
Total work = n ร— log n = O(n log n) โœ…

Step 2: Writing the Pattern (Recurrence Relation)

Instead of drawing trees every time, you can write this pattern as a formula:

For Merge Sort:

T(n) = 2 ร— T(n/2) + n

Translation:

  • T(n) = Time to sort n elements
  • 2 ร— T(n/2) = Sort two halves (each of size n/2)
  • + n = Merge the halves back together (n operations)

This is called a recurrence relation - it's just a way to write "the time for n depends on the time for smaller problems."

Example: Binary Search

Output
Click Run to execute your code

Binary Search Pattern:

T(n) = T(n/2) + 1

  • T(n/2) = Search one half
  • + 1 = Compare middle element (constant work)
  • Result: O(log n) - very fast!

Step 3: The Master Theorem (The Shortcut!)

Drawing trees is great for understanding, but there's a faster way! The Master Theorem is like a calculator for these patterns.

The Master Theorem - Simple Version

For patterns like: T(n) = a ร— T(n/b) + work

Ask one question: "Which part dominates - the recursion or the work?"

The Three Cases (Simplified)

Case 1: Recursion Dominates

When: You split into MANY subproblems (a is large)

Example: T(n) = 4T(n/2) + n

Result: The splitting dominates โ†’ O(nยฒ)

Case 2: Balanced (Most Common!)

When: Recursion and work are balanced

Examples:

  • Merge Sort: T(n) = 2T(n/2) + n โ†’ O(n log n)
  • Binary Search: T(n) = T(n/2) + 1 โ†’ O(log n)

Result: Add a log factor โ†’ O(work ร— log n)

Case 3: Work Dominates

When: You do a LOT of work at each level

Example: T(n) = 2T(n/2) + nยฒ

Result: The work dominates โ†’ O(nยฒ)

Try It Yourself!

Output
Click Run to execute your code

Quick Quiz: Classify These

Use the three cases to identify the complexity and why.

  • T(n) = 3T(n/3) + n
    Show answer Balanced: O(n log n) because n^{log_3 3} = n and the extra work matches โ†’ add a log factor.
  • T(n) = 4T(n/2) + n
    Show answer Recursion dominates: O(nยฒ) since n^{log_2 4} = n^2 and n is smaller โ†’ total is ฮ˜(n^2).
  • T(n) = T(n/2) + log n
    Show answer Slightly more than constant extra work per level โ†’ O((log n)^2) using the extended Master Theorem intuition.

Common Algorithms

Here are the patterns you'll see most often:

Algorithm Pattern Complexity Why?
Binary Search T(n) = T(n/2) + 1 O(log n) Search one half, constant work
Merge Sort T(n) = 2T(n/2) + n O(n log n) Sort both halves, merge takes n
Quick Sort (avg) T(n) = 2T(n/2) + n O(n log n) Same as merge sort on average
Tree Traversal T(n) = 2T(n/2) + 1 O(n) Visit every node once

See Merge Sort in Action

Output
Click Run to execute your code

When Master Theorem Doesn't Work

Important: Master Theorem only works when you divide by a constant (like n/2, n/3).

โŒ Fibonacci: T(n) = T(n-1) + T(n-2)

Why it doesn't work: Subtracting 1, not dividing by 2

What to do: Draw the tree - you'll see it's O(2โฟ) - exponential!

Pro Tip: When Master Theorem doesn't apply, draw the recursion tree and count levels manually. It always works!

Summary: The 3-Step Method

To Analyze Any Recursive Algorithm:

  1. Draw the recursion tree - Visualize how it breaks down
  2. Count work per level - Usually it's the same at each level
  3. Apply Master Theorem - Or count levels if it doesn't apply

Interview ready: If someone asks "How do you know?" you can show the recursion tree or write the recurrence to justify it.

Most Common Results:

  • Binary Search: O(log n) - super fast!
  • Merge Sort: O(n log n) - efficient sorting
  • Tree Traversal: O(n) - visit each node once

What's Next?

๐ŸŽ‰ Congratulations! You've completed Module 1: Introduction & Fundamentals!

You Now Know:

  • โœ… Why DSA matters for your career
  • โœ… Big O notation and complexity analysis
  • โœ… How to analyze recursive algorithms

You're ready for practical algorithms!

Next up: Module 2: Arrays & Strings where you'll learn powerful techniques like two pointers, sliding window, and solve real interview problems!

Practice Tip: Next time you see a recursive algorithm, try drawing its tree. You'll be amazed how much clearer it becomes!