๐ฌ Analyzing Recursive Algorithms
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)
Every level does n work total
Tree has log n levels
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 |
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 elements2 ร 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
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!
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) + nShow answer
Balanced: O(n log n) becausen^{log_3 3} = nand the extra work matches โ add a log factor. -
T(n) = 4T(n/2) + nShow answer
Recursion dominates: O(nยฒ) sincen^{log_2 4} = n^2andnis smaller โ total isฮ(n^2). -
T(n) = T(n/2) + log nShow 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
Click Run to execute your code
When Master Theorem Doesn't Work
โ 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!
Summary: The 3-Step Method
To Analyze Any Recursive Algorithm:
- Draw the recursion tree - Visualize how it breaks down
- Count work per level - Usually it's the same at each level
- 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!
Enjoying these tutorials?