This deck shows how to turn a recursive algorithm into a recurrence and then solve it three ways: the recursion-tree method, which multiplies the work per level by the number of levels; unrolling by repeated substitution; and the substitution method's proof by induction. It covers both equal and unequal subproblem sizes. It targets forgetting the non-recursive work, miscounting the tree depth or the nodes per level, guessing a bound without ever verifying it, and treating an unequal split as though it were balanced.
Subject: CS3000 Algorithms · 133 slides · symbolic lesson
Open the interactive version of this deck · Homework for this lesson
Objectives
By the end of this lesson you can:
Warm-up
Discussion prompt
Before we open Recurrences & Recursion Trees: without looking back, what was the main idea of Binary Search & Analyzing Loops, and what could you do by the end of it that you could not do before?
Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.
Answer:
That deck traces binary search step by step on a concrete sorted array, gives the loop invariant that proves it correct with all three obligations spelled out, explains why halving the range gives logarithmic running time, and states the general rule for counting any loop's running time. It targets the off-by-one that never shrinks the range, trusting binary search on unsorted data, mixing up linear with logarithmic growth, and invariants that are stated but not actually preserved.
Concept
Before any new material: cover the screen.
You have named 10 reusable moves so far. Say as many as you can out loud, by number, from memory.
Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.
Here they are. Score yourself.
Today adds one move to this list. Everything else you will need is already above.
The question that starts every proof from here on is not how do I begin. It is which of these applies here?
Counterexample
Discussion prompt
You have named 10 reusable moves so far. Say as many as you can out loud, by number, from memory.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Answer:
Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.
Concept
A recursive function's running time can't be written as one plain formula, because the function calls smaller copies of itself. Instead we describe it with an equation that refers to itself - a recurrence relation.
recurrence relation — An equation for a running-time function where the running time on a given input size is defined using the running time on smaller input sizes, plus a base case for the smallest inputs.
Solving a recurrence means finding a plain, self-reference-free description of the running time, stated with big-Theta or big-O.
Analogy
Discussion prompt
Explain What a recurrence relation is by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
Solving a recurrence means finding a plain, self-reference-free description of the running time, stated with big-Theta or big-O.
Picture it
Animation
Shows: When the levels are not equal — a rendered Manim animation.
Rendered with Manim.
Takeaway: A geometric series is dominated by its first term — the root does all the work.
Concept
Most divide-and-conquer recurrences share one shape. Naming its pieces now makes every worked example easier to read.
\[ T(n) = a\,T\!\left(\frac{n}{b}\right) + f(n) \]
In plain words: a is how many recursive calls are made, b is the factor the input shrinks by in each call, and f of n is all the non-recursive work done at that call.
non-recursive work — Everything a call does besides making its recursive calls - splitting the input, combining results, comparisons, loops. Often written as f(n) in the general shape.
Explain it
Discussion prompt
Explain The general shape of a divide-and-conquer recurrence to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
Most divide-and-conquer recurrences share one shape. Naming its pieces now makes every worked example easier to read.
Intuition
Picture a recursive call as a Russian nesting doll. Opening one reveals a smaller doll inside, which opens to reveal an even smaller one, until you reach the tiniest doll that doesn't open at all - the base case.
The recurrence describes exactly this: the cost of one doll equals the cost of the smaller doll inside it, plus whatever extra work it took to open this particular doll.
Concept
When a function is recursive, the first thing to find is every place it calls itself, and what size input it passes each time.
Count the calls: is it one call, two, three? Note the size passed to each: is it half the input, all but one element, some other fraction?
Concept
A recurrence is not invented. It is read off the code in three passes: how many recursive calls, how big each one is, and how much work happens outside them.
SOLVE(A, n)
if n == 1
return A[1]
left = SOLVE(first half of A)
right = SOLVE(second half of A)
for i = 1 to n
merge A[i] into the answer
return the merged answerTwo calls on lines 4 and 5, each on half the input, and a loop on line 6 that touches every element once. That is where the two, the halving, and the linear term in the recurrence each come from — one per line.
Notation
Every line of SOLVE says one thing. Read the line, then read what it does — not the other way round.
Annotate
Invariant
Watch the rightmost column. The number of calls doubles and the size halves, and those two changes cancel exactly — so every level does the same total work. That cancellation is the whole recursion-tree method.
Step through it
Before revealing each level's work, multiply the calls by the size yourself and predict it.
Picture it
Animation
Shows: SOLVE executing: the current line of pseudocode is highlighted while the data it touches changes.
Rendered with Manim.
Takeaway: Two calls at half size each, plus linear work per call: every level costs the same, and there are about log n levels.
Concept
Next, find everything the function does that is NOT a recursive call - loops, comparisons, splitting the input, combining results.
This is the part students most often skip entirely. It becomes the extra term added onto the recursive calls in the recurrence.
Concept
Every recurrence needs a base case: the smallest input size, where the function returns directly without calling itself. Its cost is treated as a constant.
For the rest of this lesson, assume the input size is a power of two, so every halving comes out exact with no leftover pieces to round.
Picture it
Animation
Shows: Base cases decide the constant, not the class — a rendered Manim animation.
Rendered with Manim.
Takeaway: Which is why asymptotic analysis lets you be casual about them.
Ranking
Put in order
Put the moves of From code to recurrence: a merge-style function into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Two calls appear: mergeSort on the left half and mergeSort on the right half.
Worked example
Read this function and turn it into a recurrence.
function mergeSort(A, n):
if n <= 1:
return A
left = mergeSort(A[0 .. n/2 - 1], n/2)
right = mergeSort(A[n/2 .. n-1], n/2)
return merge(left, right) // merge scans all n elements onceFind every place the function calls itself
Why: Two calls appear: mergeSort on the left half and mergeSort on the right half.
Note the size passed to each recursive call
Why: Both halves have size n divided by two (n is assumed to be a power of two, so the split is exact).
Find the work done outside the recursive calls
Why: The merge step scans every one of the n elements once to combine the two sorted halves - that is n units of non-recursive work.
Assemble the recurrence
Why: Two calls of size n/2 contribute the 2T(n/2) term; the merge step contributes the extra n.
\[ T(n) = 2T\!\left(\frac{n}{2}\right) + n, \qquad T(1) = \Theta(1) \]
Verify the recurrence against a tiny case
Why: For n = 2: mergeSort makes two calls of size 1 (each a base case) plus a merge that scans 2 elements. That matches T(2) = 2T(1) + 2 exactly as the formula says.
Worked example
Binary search only ever follows one half of the array. Turn it into a recurrence.
function binarySearch(A, target, n):
if n == 0:
return NOT_FOUND
mid = n / 2
if A[mid] == target:
return mid
else:
return binarySearch(halfOf(A), target, n/2) // only ONE half is searchedFind the recursive calls
Why: Exactly one recursive call appears, on whichever half contains the target - the other half is thrown away.
Note the size passed
Why: The one call receives n/2 elements.
Find the non-recursive work
Why: Checking the middle element against the target is a single comparison - constant work, not proportional to n.
Assemble the recurrence
Why: One call of size n/2, plus one constant-time comparison.
\[ T(n) = T\!\left(\frac{n}{2}\right) + 1, \qquad T(1) = \Theta(1) \]
Verify by tracing n = 8
Why: One call shrinks the array to 4, then 2, then 1: three halvings plus one constant check each time, matching T(8) unrolled through T(4), T(2), and T(1).
Picture it
Animation
Shows: Reading a recurrence off the code — a rendered Manim animation.
Rendered with Manim.
Takeaway: Recursive structure gives the left half; the non-recursive work gives the right.
Step zero
Discussion prompt
Practice: a function with three recursive calls — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Find the recursive calls
Answer:
Worked example
This function calls itself three times. Write its recurrence.
function spread(n):
if n <= 1:
return
spread(n/2)
spread(n/2)
spread(n/2)
// no other work happens hereFind the recursive calls
Why: Three separate calls appear, one after another.
Note the size passed to each
Why: All three calls receive n/2.
Find the non-recursive work
Why: There is nothing here besides the three calls themselves - only constant overhead for making the calls.
Assemble the recurrence
Why: Three calls of size n/2, plus one unit of constant overhead.
\[ T(n) = 3T\!\left(\frac{n}{2}\right) + 1 \]
Verify by counting calls at n = 4
Why: The call on 4 makes three calls on 2, and each of those makes three calls on 1. That matches T(4) = 3T(2) + 1 with T(2) = 3T(1) + 1 underneath it.
Picture it
Animation
Shows: Each line of the worked example "Practice: a function with three recursive calls", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: The call on 4 makes three calls on 2, and each of those makes three calls on 1. That matches T(4) = 3T(2) + 1 with T(2) = 3T(1) + 1 underneath it.
Anomaly
Predict first
A student writes this, and it looks reasonable:
A student glances at the merge-sort code, sees the two recursive calls, and stops there - never noticing the merge step happens too.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: With no extra work at internal nodes, only the base-case leaves contribute anything.
Every level of code that runs between the recursive calls counts too - here, the merge step scans all n elements.
Why: With no extra work at internal nodes, only the base-case leaves contribute anything. There are n leaves, each costing a constant, so this (incorrect) recurrence gives a total of only n.
Trap
A student glances at the merge-sort code, sees the two recursive calls, and stops there - never noticing the merge step happens too.
\[ \text{Wrong: } T(n) = 2T\!\left(\frac{n}{2}\right) \]
Solve the wrong recurrence with a tree
Why: With no extra work at internal nodes, only the base-case leaves contribute anything. There are n leaves, each costing a constant, so this (incorrect) recurrence gives a total of only n.
\[ \text{(wrong) total} = n \cdot \Theta(1) = \Theta(n) \]
Every level of code that runs between the recursive calls counts too - here, the merge step scans all n elements.
\[ \text{Right: } T(n) = 2T\!\left(\frac{n}{2}\right) + n \]
Solve the correct recurrence with a tree
Why: Now every internal node also contributes n units of merge work per level, and there are about log2(n) levels, giving a much larger total.
\[ \text{(right) total} = \Theta(n \log n) \]
Notation
Annotate
From Trap: forgetting the non-recursive work — read this one piece at a time. What is each part doing?
On: \( \text{Wrong: } T(n) = 2T\!\left(\frac{n}{2}\right) \)
Concept
One reliable way to solve a recurrence is to draw it as a tree: the root is the original call, and each node's children are the recursive calls it makes.
Add up the work done at each level of the tree, then add up all the levels. That total is the running time.
Intuition
Every call becomes a node; every recursive call it makes becomes a child pointing down from it. The whole tree is just the recursion unrolled into a picture.
Reading the tree level by level turns an abstract equation into something you can literally count.
Picture it
Animation
Shows: Cost by level — a rendered Manim animation.
Rendered with Manim.
Takeaway: When every level costs the same, multiply by the depth.
Concept
At any single level of the tree, the work done there is the number of nodes at that level, times the non-recursive work each of those nodes does.
level — All the nodes in the tree that are the same number of recursive calls away from the root. Level 0 is the root itself.
Concept
Every proof of this kind has the same five or six moves in the same order. The order is not something you rediscover each time.
It is on the right. It will stay on the right through the worked examples that follow.
Why this matters: the structure is now handled. You are not spending working memory on what comes next — you are spending all of it on the one hard step.
Step 3 is a mechanical grind and step 5 is arithmetic. Step 4 is where the answer is decided — get the level count wrong and every later step is wasted.
Picture it
Animation
Shows: Changing variables — a rendered Manim animation.
Rendered with Manim.
Takeaway: Substitution turns an unrecognisable recurrence into one you have solved.
Concept
The tree's depth is how many times the input can be cut by the shrink factor before it reaches the base-case size.
\[ \frac{n}{2^{d}} = 1 \ \Longrightarrow\ d = \log_2 n \]
So a recurrence that halves the input at every call has a depth proportional to a logarithm - far fewer levels than the input size itself.
Intuition
What move should we make next?
Here is the recurrence and the shape of its tree:
\[ T(n) = 2T(n/2) + n \]
Two children per node, each on half the input, plus n units of work at the node itself.
You could try to total the whole tree at once, or you could compute something smaller first. Which, and why does the order matter?
_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.
Picture it
Animation
Shows: Tree first, theorem second — a rendered Manim animation.
Rendered with Manim.
Takeaway: Learn the tree — it works on every recurrence, not just the tidy ones.
Estimation
Predict first
Build the tree for the merge-sort recurrence level by level.
Commit before you compute: what does Level-by-level pattern for T(n) = 2T(n/2) + n come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify the pattern continues at level 3
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Level 3 has 8 nodes, each of size n/8, each doing n/8 units of work: 8 times n/8 is n once more.
Worked example
Build the tree for the merge-sort recurrence level by level.
\[ T(n) = 2T\!\left(\frac{n}{2}\right) + n \]
Compute level 0
Why: One node (the root), size n, doing n units of non-recursive work.
Compute level 1
Why: Two nodes, each of size n/2, each doing n/2 units of work. Total for the level: 2 times n/2, which is n.
Compute level 2
Why: Four nodes, each of size n/4, each doing n/4 units of work. Total for the level: 4 times n/4, which is again n.
Verify the pattern continues at level 3
Why: Level 3 has 8 nodes, each of size n/8, each doing n/8 units of work: 8 times n/8 is n once more.
| level | nodes | work per node | level total |
|---|---|---|---|
| 0 | 1 | n | n |
| 1 | 2 | n/2 | n |
| 2 | 4 | n/4 | n |
| 3 | 8 | n/8 | n |
Worked example
Every level totals n. Now add up all the levels.
Figure (svg): A recursion tree: root labeled n, two children each labeled n over 2, four grandchildren each labeled n over 4, with each level noted as totaling n
Count the levels
Why: The size halves each level, from n down to 1, so there are log2(n) plus 1 levels in total.
\[ \text{levels} = \log_2 n + 1 \]
Multiply level total by number of levels
Why: Every level contributes exactly n, and there are log2(n) plus 1 of them.
\[ T(n) = n\left(\log_2 n + 1\right) = \Theta(n \log n) \]
| level | nodes | work per node | level total |
|---|---|---|---|
| 0 | 1 | n | n |
| 1 | 2 | n/2 | n |
| ... | ... | ... | ... |
| log2(n) | n | 1 | n |
Verify with a concrete value
Why: For n = 8, unrolling by hand gives T(1)=1, T(2)=4, T(4)=12, T(8)=32. The formula gives n(log2(n)+1) = 8 times 4, which is 32 - an exact match.
Pattern
Step through it
Step through The full recursion tree for T(n) = 2T(n/2) + n one row at a time. What is driving the change, and what would the row after the last one be?
Picture it
Animation
Shows: An unbalanced tree — a rendered Manim animation.
Rendered with Manim.
Takeaway: Levels still cost n each, so the answer is still n log n.
Fill the middle
Fill in the blanks
From The move we just made, named — finish the line. Write what belongs on the right of the equals sign before you look.
2^n \quad \text{for every level } i \cdot \frac______} = ___
Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. Level i has 2 to the i nodes, each doing n over 2 to the i work.
Concept
The move: #11 (Unroll and sum the levels), then #10 (Halve and count).
Compute work per level, not work per node
Why: Level i has 2 to the i nodes, each doing n over 2 to the i work. Those cancel: every level costs exactly n. Trying to total node by node would have buried that.
\[ 2^{i} \cdot \frac{n}{2^{i}} = n \quad \text{for every level } i \]
Count the levels with move #10
Why: The input halves each level and stops at 1, so there are log base 2 of n levels — the same halving count you used for binary search.
\[ T(n) = \underbrace{n}_{\text{per level}} \times \underbrace{\log_{2} n}_{\text{levels}} = \Theta(n \log n) \]
Work per level times number of levels. When the per-level work is not constant, you sum instead of multiply — but you still compute per-level first.
Anomaly
Predict first
A student writes this, and it looks reasonable:
A student assumes the tree grows the way a level number does: level i has i nodes, and the tree has n levels.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: This mistakes the level's index for its size.
Count nodes by how many times the tree has branched, not by the level number itself.
Why: This mistakes the level's index for its size. But every node at level 2 has two children, so level 3 must have twice as many nodes as level 2, not three total.
Trap
A student assumes the tree grows the way a level number does: level i has i nodes, and the tree has n levels.
\[ \text{Wrong: level } i \text{ has } i \text{ nodes; depth} = n \]
Guess level 3 has 3 nodes
Why: This mistakes the level's index for its size. But every node at level 2 has two children, so level 3 must have twice as many nodes as level 2, not three total.
Count nodes by how many times the tree has branched, not by the level number itself.
\[ \text{Right: level } i \text{ has } 2^{i} \text{ nodes; depth} = \log_2 n + 1 \]
Check level 3 directly
Why: Level 0 has 1 node, level 1 has 2, level 2 has 4 - doubling each time - so level 3 has 8, matching 2 to the third power, not 3.
Concept
In the last tree, every level happened to total the same amount of work: n. That is a feature of this particular recurrence, not a rule for every recurrence.
Does the level total stay the same if the non-recursive work is bigger - work that grows with the square of the input instead of just the input itself? Same branching shape, different extra work. Let's redo the tree.
Step zero
Discussion prompt
Recursion tree for T(n) = 4T(n/2) + n squared — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Compute level 0
Answer:
Worked example
Four recursive calls this time, each on half the input, with quadratic non-recursive work.
\[ T(n) = 4T\!\left(\frac{n}{2}\right) + n^{2} \]
Compute level 0
Why: One node, size n, doing n squared units of work.
Compute level 1
Why: Four nodes, each of size n/2, each doing (n/2) squared units of work. Total: 4 times n squared over 4, which is n squared again.
Compute level 2
Why: Sixteen nodes, each of size n/4, each doing (n/4) squared units of work. Total: 16 times n squared over 16, which is still n squared.
| level | nodes | work per node | level total |
|---|---|---|---|
| 0 | 1 | n^2 | n^2 |
| 1 | 4 | (n/2)^2 | n^2 |
| 2 | 16 | (n/4)^2 | n^2 |
| ... | ... | ... | ... |
Multiply the level total by the number of levels
Why: Every level still totals n squared, and there are log2(n) plus 1 levels, exactly like before - only the per-level amount changed.
\[ T(n) = n^{2}\left(\log_2 n + 1\right) = \Theta(n^{2} \log n) \]
Verify with a concrete value
Why: For n = 8 with T(1) = 1: T(2)=8, T(4)=48, T(8)=256. The formula gives n squared times (log2(n)+1) = 64 times 4, which is 256 - an exact match.
Picture it
Animation
Shows: Each line of the worked example "Recursion tree for T(n) = 4T(n/2) + n squared", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: For n = 8 with T(1) = 1: T(2)=8, T(4)=48, T(8)=256. The formula gives n squared times (log2(n)+1) = 64 times 4, which is 256 - an exact match.
Intuition
The branching pattern - four children, each half size - was identical to a case with only two children. Only the per-call work changed from linear to quadratic, yet the final total jumped from an n-log-n behavior to an n-squared-log-n behavior.
This is exactly why the recursion tree is worth drawing every time: the branching alone never tells you the answer. What happens at each node matters just as much.
Concept
A second way to solve a recurrence is to substitute its own definition into itself, over and over, until a pattern for the running time appears.
unrolling — Replacing every occurrence of the running-time function on the right-hand side with the recurrence's own definition, one substitution at a time, to expose the pattern after k steps.
Intuition
Each substitution peels back one layer of the recursion, the way opening one envelope reveals a smaller envelope inside, plus a note about what happened at this layer.
Keep peeling until you reach the base case, then read off everything the notes added up to.
Picture it
Animation
Shows: Unrolling by hand — a rendered Manim animation.
Rendered with Manim.
Takeaway: Expand three levels, spot the pattern, then prove it.
Estimation
Predict first
Substitute the recurrence into itself and watch the pattern emerge.
Commit before you compute: what does Unroll T(n) = T(n/2) + 1 come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify with n = 8
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Here k = 3 since 2 cubed is 8, so T(8) = T(1) + 3 = 4, matching the hand trace of three halvings plus one base case check from the binary-search example.
Worked example
Substitute the recurrence into itself and watch the pattern emerge.
\[ T(n) = T\!\left(\frac{n}{2}\right) + 1 \]
Substitute once
Why: Replace T(n/2) using the same recurrence, then combine the constants.
\[ T(n) = \left[T\!\left(\tfrac{n}{4}\right) + 1\right] + 1 = T\!\left(\tfrac{n}{4}\right) + 2 \]
Substitute again
Why: Replace T(n/4) the same way.
\[ T(n) = T\!\left(\tfrac{n}{8}\right) + 3 \]
Spot the pattern after k substitutions
Why: Each substitution divides the argument by 2 again and adds 1 more to the running total.
\[ T(n) = T\!\left(\frac{n}{2^{k}}\right) + k \]
Stop when the subproblem hits the base case
Why: The subproblem size is 1 when n over 2 to the k equals 1, which happens at k equals log2(n).
\[ \frac{n}{2^{k}} = 1 \Rightarrow k = \log_2 n \ \Rightarrow\ T(n) = T(1) + \log_2 n = \Theta(\log n) \]
Verify with n = 8
Why: Here k = 3 since 2 cubed is 8, so T(8) = T(1) + 3 = 4, matching the hand trace of three halvings plus one base case check from the binary-search example.
Picture it
Animation
Shows: Each line of the worked example "Unroll T(n) = T(n/2) + 1", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Here k = 3 since 2 cubed is 8, so T(8) = T(1) + 3 = 4, matching the hand trace of three halvings plus one base case check from the binary-search example.
Ranking
Put in order
Put the moves of Unroll T(n) = 2T(n/2) + n to confirm the tree result into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Replace T(n/2), distribute the 2, and combine the two n terms.
Worked example
Do the same unrolling for the merge-sort recurrence and check it matches the tree.
\[ T(n) = 2T\!\left(\frac{n}{2}\right) + n \]
Substitute once
Why: Replace T(n/2), distribute the 2, and combine the two n terms.
\[ T(n) = 2\left[2T\!\left(\tfrac{n}{4}\right) + \tfrac{n}{2}\right] + n = 4T\!\left(\tfrac{n}{4}\right) + 2n \]
Substitute again
Why: Replace T(n/4) the same way.
\[ T(n) = 8T\!\left(\tfrac{n}{8}\right) + 3n \]
Spot the pattern after k substitutions
Why: The coefficient in front of T doubles each time (2 to the k), and the accumulated extra work grows by n each time (k times n).
\[ T(n) = 2^{k}\,T\!\left(\frac{n}{2^{k}}\right) + k\,n \]
Stop at the base case
Why: The subproblem reaches size 1 when k equals log2(n), giving n copies of the constant base cost plus n log2(n) of accumulated work.
\[ k = \log_2 n \ \Rightarrow\ T(n) = n\,T(1) + n\log_2 n = \Theta(n \log n) \]
Verify with n = 8
Why: Here k = 3: T(8) = 8 times T(1) plus 3 times 8, which is 8 plus 24, equal to 32 - matching the recursion-tree result exactly.
Picture it
Animation
Shows: Each line of the worked example "Unroll T(n) = 2T(n/2) + n to confirm the tree result", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Here k = 3: T(8) = 8 times T(1) plus 3 times 8, which is 8 plus 24, equal to 32 - matching the recursion-tree result exactly.
Concept
After k substitutions, a recurrence's right-hand side settles into a predictable shape: some multiplier on the running time of a much smaller input, plus an accumulated amount of extra work from all the layers peeled so far.
The trick is always the same: substitute a few times by hand, guess the pattern for a general k, then figure out which k makes the small input hit the base case.
Concept
The substitution method has two parts. First, guess a bound for the running time - usually informed by the recursion tree or the unrolled pattern. Second, prove that guess correct using mathematical induction.
Skipping the second part is the single most common mistake with this method. A guess, however well-motivated, is not yet a fact.
Intuition
The recursion tree and unrolling are wonderful for spotting a pattern, but a sketch can hide a small error - a term that doesn't quite cancel, a case that behaves differently.
Induction closes that gap. It confirms the guess holds for every input size, not just the handful you sketched by hand.
Concept
Before writing any algebra, state three things plainly.
First, the guess: an inequality bounding the running time, with a constant left unknown for now.
Second, the inductive hypothesis: assume the guess already holds for the smaller input size that appears on the right-hand side of the recurrence.
Third, the goal: use the recurrence's own definition, plus that assumption, to show the same guess also holds for the original input size.
Intuition
What feels wrong about this?
The recursion tree gave a clean answer:
\[ T(n) = \Theta(n \log n) \]
The tree was drawn correctly, the levels were counted correctly, the arithmetic checks out.
_Plain English only. No notation, no algebra. Just say what bothers you._
The feeling: the tree is a picture of a few levels and then a row of dots. Nobody proved the dots behave like the levels you drew.
That feeling is the proof. It is not a substitute for the proof — it is the thing the proof writes down.
So the tree is a guess generator, and the substitution method is the proof. You will do exactly what you did in lesson 3: assume the bound for smaller inputs and derive it for n.
Estimation
Predict first
Prove, by induction, that the recursion-tree guess actually holds for every n.
Commit before you compute: what does Substitution method: T(n) = 2T(n/2) + n is O(n log n) come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify the base case with a concrete constant
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Pick c = 2, which also satisfies c at least 1 above.
Worked example
Prove, by induction, that the recursion-tree guess actually holds for every n.
\[ T(n) = 2T\!\left(\frac{n}{2}\right) + n,\qquad T(1)=1 \]
State the guess
Why: Aim to show T(n) is at most a constant c times n times log2(n), for every n that is a power of two and at least 2.
\[ \text{Guess: } T(n) \le c\,n\log_2 n \quad (n \ge 2) \]
State the inductive hypothesis
Why: For the inductive step, assume the guess already holds for the smaller size n/2 (valid once n/2 is itself at least 2, i.e. n is at least 4).
\[ T\!\left(\frac{n}{2}\right) \le c\,\frac{n}{2}\log_2\!\left(\frac{n}{2}\right) \]
Substitute the hypothesis into the recurrence
Why: Replace T(n/2) in the recurrence with the bound the hypothesis provides.
\[ T(n) \le 2\left[c\,\frac{n}{2}\log_2\!\left(\frac{n}{2}\right)\right] + n = c\,n\log_2\!\left(\frac{n}{2}\right) + n \]
Simplify with the logarithm identity
Why: log2(n/2) equals log2(n) minus 1, so distributing and collecting terms isolates exactly the guess plus a leftover.
\[ T(n) \le c\,n\big(\log_2 n - 1\big) + n = c\,n\log_2 n - (c-1)\,n \]
Choose c so the leftover term disappears
Why: Whenever c is at least 1, the leftover term (c-1) times n is at least 0, so subtracting it only shrinks the bound, keeping T(n) at most c n log2(n).
\[ c \ge 1 \ \Rightarrow\ T(n) \le c\,n\log_2 n \]
Verify the base case with a concrete constant
Why: Pick c = 2, which also satisfies c at least 1 above. At n = 2, the guess says T(2) is at most 2 times 2 times log2(2), which is 4; the recurrence gives T(2) = 2T(1)+2 = 4. Since 4 is at most 4, the base case holds, so by induction T(n) is at most 2 n log2(n) for every n at least 2 - matching the recursion tree's Theta(n log n) answer.
Picture it
Animation
Shows: The substitution method — a rendered Manim animation.
Rendered with Manim.
Takeaway: A guess plus a proof. The tree is usually how you get the guess.
Anomaly
Predict first
A student writes this, and it looks reasonable:
A student glances at the recursion tree, guesses the total is proportional to just n, and stops - confident, but never running the induction check.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: Substituting the guess into the recurrence gives 2 times c times n over 2, plus n, which is (c+1) times n.
Always complete the substitution proof before trusting a guess - it either confirms the bound or tells you exactly how to fix it.
Why: Substituting the guess into the recurrence gives 2 times c times n over 2, plus n, which is (c+1) times n. That is never at most c times n for any fixed positive c, since (c+1)n is always bigger. The induction step cannot close - the guess was too small, and skipping the check let the error slide.
Trap
A student glances at the recursion tree, guesses the total is proportional to just n, and stops - confident, but never running the induction check.
\[ \text{Unverified guess: } T(n) \le c\,n \]
See what the check would have shown
Why: Substituting the guess into the recurrence gives 2 times c times n over 2, plus n, which is (c+1) times n. That is never at most c times n for any fixed positive c, since (c+1)n is always bigger. The induction step cannot close - the guess was too small, and skipping the check let the error slide.
\[ T(n) \le 2\!\left(c\tfrac{n}{2}\right) + n = (c+1)n \ \not\le\ c\,n \]
Always complete the substitution proof before trusting a guess - it either confirms the bound or tells you exactly how to fix it.
\[ \text{Corrected guess: } T(n) \le c\,n\log_2 n \]
Run the check and see it close
Why: With the bigger guess, the same substitution leaves c n log2(n) minus (c-1)n, which is at most c n log2(n) for c at least 1 - the induction step closes, as shown in the previous worked example.
Translation
\( T(n) \le 2\!\left(c\tfrac{n}{2}\right) + n = (c+1)n \ \not\le\ c\,n \)
Draw it
Translate both ways. First write the expression above as a sentence with no symbols in it at all. Then cover it, and write your sentence back as notation. If the two versions disagree, the disagreement is the thing to fix.
Step zero
Discussion prompt
Substitution method: T(n) = 4T(n/2) + n squared is O(n squared log n) — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: State the guess
Answer:
Worked example
Prove the recursion-tree guess for the quadratic-work recurrence, using the same recipe.
\[ T(n) = 4T\!\left(\frac{n}{2}\right) + n^{2},\qquad T(1)=1 \]
State the guess
Why: Aim to show T(n) is at most a constant c times n squared times log2(n), for n a power of two and at least 2.
\[ \text{Guess: } T(n) \le c\,n^{2}\log_2 n \]
State the inductive hypothesis
Why: Assume the guess already holds at n/2 (valid once n is at least 4).
\[ T\!\left(\frac{n}{2}\right) \le c\left(\frac{n}{2}\right)^{2}\log_2\!\left(\frac{n}{2}\right) \]
Substitute and simplify with the logarithm identity
Why: Replace T(n/2), expand (n/2) squared as n squared over 4, and use log2(n/2) equals log2(n) minus 1.
\[ T(n) \le 4\left[c\,\frac{n^{2}}{4}\log_2\!\left(\frac{n}{2}\right)\right] + n^{2} = c\,n^{2}\log_2 n - (c-1)n^{2} \]
Choose c so the leftover term disappears
Why: For any c at least 1, the leftover term is at least 0, so T(n) stays at most c n squared log2(n) - the same reasoning as the linear-work example.
\[ c \ge 1 \ \Rightarrow\ T(n) \le c\,n^{2}\log_2 n \]
Verify the base case with c = 2
Why: At n = 2: the guess says T(2) is at most 2 times 4 times log2(2), which is 8; the recurrence gives T(2) = 4T(1)+4 = 8. Since 8 is at most 8, the base case holds, so T(n) is at most 2 n squared log2(n) for every n at least 2 - the same constant that worked in the linear-work case.
Picture it
Animation
Shows: Each line of the worked example "Substitution method: T(n) = 4T(n/2) + n squared is O(n squared log n)", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: At n = 2: the guess says T(2) is at most 2 times 4 times log2(2), which is 8; the recurrence gives T(2) = 4T(1)+4 = 8. Since 8 is at most 8, the base case holds, so T(n) is at most 2 n squared log2(n) for every n at least 2 - the same constant that worked in the linear-work case.
Anomaly
Predict first
A student writes this, and it looks reasonable:
Mid-proof, a student needs to simplify log2(n/2) but keeps it unchanged, as if dividing the argument by 2 did nothing to the logarithm.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: With that substitution, the c n log2(n) minus (c-1)n cancellation never appears - the algebra just reproduces 2 times c times (n/2) log2(n), plus n, which equals c n log2(n) plus n, and now nothing has been shown to be…
Dividing the argument of a logarithm by 2 always subtracts exactly 1 from the logarithm's value (base 2).
Why: With that substitution, the c n log2(n) minus (c-1)n cancellation never appears - the algebra just reproduces 2 times c times (n/2) log2(n), plus n, which equals c n log2(n) plus n, and now nothing has been shown to be at most the guess.
Trap
Mid-proof, a student needs to simplify log2(n/2) but keeps it unchanged, as if dividing the argument by 2 did nothing to the logarithm.
\[ \text{Wrong: } \log_2\!\left(\frac{n}{2}\right) = \log_2 n \]
See the proof stall
Why: With that substitution, the c n log2(n) minus (c-1)n cancellation never appears - the algebra just reproduces 2 times c times (n/2) log2(n), plus n, which equals c n log2(n) plus n, and now nothing has been shown to be at most the guess.
\[ c\,n\log_2 n + n \ \not\le\ c\,n\log_2 n \]
Dividing the argument of a logarithm by 2 always subtracts exactly 1 from the logarithm's value (base 2).
\[ \text{Right: } \log_2\!\left(\frac{n}{2}\right) = \log_2 n - 1 \]
See the proof close
Why: Expanding correctly turns the extra n term into minus (c-1) times n, which is at most 0 once c is at least 1 - exactly the cancellation the earlier worked example relied on.
Break the constraint
Discussion prompt
The rule this trap just fixed:
Dividing the argument of a logarithm by 2 always subtracts exactly 1 from the logarithm's value (base 2).
Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?
Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.
Answer:
With that substitution, the c n log2(n) minus (c-1)n cancellation never appears - the algebra just reproduces 2 times c times (n/2) log2(n), plus n, which equals c n log2(n) plus n, and now nothing has been shown to be at most the guess.
Concept
Three recurrences, three totals - all reached with the same recursion-tree and substitution tools.
| Recurrence | Work per level | Number of levels | Total |
|---|---|---|---|
| T(n) = 2T(n/2) + n | n (constant) | log2(n) + 1 | Theta(n log n) |
| T(n) = 4T(n/2) + n^2 | n^2 (constant) | log2(n) + 1 | Theta(n^2 log n) |
| T(n) = T(n/2) + 1 | 1 (constant) | log2(n) + 1 | Theta(log n) |
Comparison
Comparison matrix
From Comparing the shapes solved so far: refill the Work per level column from what you know. The rest of the table is as it appeared.
| Recurrence | Work per level | Number of levels | Total |
|---|---|---|---|
| T(n) = 2T(n/2) + n | n (constant) | log2(n) + 1 | Theta(n log n) |
| T(n) = 4T(n/2) + n^2 | n^2 (constant) | log2(n) + 1 | Theta(n^2 log n) |
| T(n) = T(n/2) + 1 | 1 (constant) | log2(n) + 1 | Theta(log n) |
Concept
So far every recursive call has split the input into two equal halves. Many real divide-and-conquer algorithms do not split evenly at all.
A classic example: one recursive call gets a third of the input, and the other gets the remaining two-thirds.
Intuition
Picture two paths down the tree: one path always takes the smaller piece and shrinks to nothing quickly; the other always takes the bigger piece and lingers much longer before it, too, bottoms out.
The tree is not finished until every branch, including the slowest one, has reached the base case.
Concept
For an uneven split, the number of levels in the tree is decided by whichever branch shrinks the slowest - the one that keeps the largest fraction of the input at every step.
That branch takes the most steps to reach the base case, and no level of the tree is truly finished until that branch gets there too.
Intuition
At any level, the pieces present might be different sizes, but if every recursive call still receives its own share of the same parent, the pieces at that level still add back up to the original size.
That is why the level total can still work out to about the same amount, even though the individual pieces are no longer equal to each other.
Fill the middle
Fill in the blanks
From Process: assuming the split is balanced — finish the line. Write what belongs on the right of the equals sign before you look.
T(n) = T(n/3) + T(2n/3) + n
Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. The last recurrence had two children and depth log base 2 of n, so reuse that.
Intuition
Watch me not know the answer. This is what the first two minutes actually look like.
A recurrence where the two pieces are not the same size:
\[ T(n) = T(n/3) + T(2n/3) + n \]
Try treating it like the balanced case: two children, so depth log base 2 of n
Why: The last recurrence had two children and depth log base 2 of n, so reuse that. It is the obvious first move.
The two branches do not reach the bottom together
Why: The n/3 branch bottoms out after log base 3 of n levels. The 2n/3 branch keeps going. A single depth number does not describe this tree, so the reused formula does not apply.
Dead end. Not a mistake — a move that was worth trying and did not pay off. This happens in most proofs.
Back up. Ask which branch sets the depth
Why: Depth is set by the branch that shrinks slowest — the 2n/3 one — because the tree is not finished until every branch is finished.
\[ \left(\tfrac{2}{3}\right)^{k} n = 1 \;\Longrightarrow\; k = \log_{3/2} n \]
Work per level is still at most n, so the total is O(n log n) — same answer as the balanced case, reached by a genuinely different route.
The expert does not see the whole path in advance. The expert tries something, reads the result, and adjusts. That is the skill.
Notation
Annotate
From Process: assuming the split is balanced — read this one piece at a time. What is each part doing?
On: \( \left(\tfrac{2}{3}\right)^{k} n = 1 \;\Longrightarrow\; k = \log_{3/2} n \)
Picture it
Figure (svg): A recursion tree: root labeled n splits into a left child labeled n over 3 and a right child labeled two n over 3; the right side keeps branching further because it shrinks more slowly
Discussion prompt
Read the picture before the words. What is this showing, and what is the one thing it is built to make obvious? Commit to an answer, then read on.
Hint: Name the parts, then say what changes between them — and if nothing changes, say what is being held still.
Answer:
One recursive call keeps a third of the input, the other keeps two-thirds, plus n units of extra work.
Worked example
One recursive call keeps a third of the input, the other keeps two-thirds, plus n units of extra work.
Figure (svg): A recursion tree: root labeled n splits into a left child labeled n over 3 and a right child labeled two n over 3; the right side keeps branching further because it shrinks more slowly
Compute level 0 and level 1
Why: Level 0 is one node of size n, doing n work. Level 1 has two nodes, sizes n/3 and 2n/3, whose non-recursive work adds up to n/3 plus 2n/3, which is n again.
| level | sizes present | total size at level |
|---|---|---|
| 0 | n | n |
| 1 | n/3, 2n/3 | n |
Compute level 2
Why: The n/3 node splits into n/9 and 2n/9; the 2n/3 node splits into 2n/9 and 4n/9. Adding all four: n/9 + 2n/9 + 2n/9 + 4n/9 is 9n/9, which is n once more.
Find the depth of each branch
Why: The fast branch (always keeping a third) reaches size 1 after log base 3 of n steps. The slow branch (always keeping two-thirds) needs log base three-halves of n steps, since it shrinks by a factor closer to 1 each time.
\[ \text{fast depth} = \log_3 n, \qquad \text{slow depth} = \log_{3/2} n \]
Verify both depths are Theta(log n)
Why: By the change-of-base formula, log base 3 of n equals log2(n) divided by log2(3), about 1.585, and log base three-halves of n equals log2(n) divided by log2(1.5), about 0.585. Both are just a constant multiple of log2(n), so the tree has Theta(log n) levels either way, and since every full level totals about n, the whole tree costs Theta(n log n).
Comparison
Comparison matrix
From Recursion tree for T(n) = T(n/3) + T(2n/3) + n: refill the sizes present column from what you know. The rest of the table is as it appeared.
| level | sizes present | total size at level |
|---|---|---|
| 0 | n | n |
| 1 | n/3, 2n/3 | n |
Picture it
Animation
Shows: A recursion tree, level by level — a rendered Manim animation.
Rendered with Manim.
Takeaway: Add across each level, then add the levels. That is the whole method.
Anomaly
Predict first
A student writes this, and it looks reasonable:
A student sees T(n) = T(n/3) + T(2n/3) + n and, out of habit, assumes both branches behave like a balanced n/2, n/2 split.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: Using the balanced-case logarithm undercounts the tree's true height, because the two-thirds branch shrinks more slowly than a one-half branch and is still splitting further down than this estimate assumes.
Use the actual shrink factor of the slowest branch, not an assumed halfway split.
Why: Using the balanced-case logarithm undercounts the tree's true height, because the two-thirds branch shrinks more slowly than a one-half branch and is still splitting further down than this estimate assumes.
Trap
A student sees T(n) = T(n/3) + T(2n/3) + n and, out of habit, assumes both branches behave like a balanced n/2, n/2 split.
\[ \text{Wrong: both branches reach the base case after } \log_2 n \text{ steps} \]
Stop counting levels too early
Why: Using the balanced-case logarithm undercounts the tree's true height, because the two-thirds branch shrinks more slowly than a one-half branch and is still splitting further down than this estimate assumes.
Use the actual shrink factor of the slowest branch, not an assumed halfway split.
\[ \text{Right: slow branch depth} = \log_{3/2} n \]
Keep summing until every branch has bottomed out
Why: Some nodes near the fast branch become leaves early and stop contributing extra work, while the slow branch keeps branching and contributing full-level work well past that point - the tree's total height is set by that slower branch, as shown in the previous worked example.
Two truths and a lie
Sort into buckets
Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.
Concept
Not every recursive call divides the input. Some shrink it by a fixed amount instead - the classic pattern is one recursive call on everything except a single element.
Same tools apply: find the recursive calls, find the extra work, write the recurrence, then solve it.
Intuition
Dividing in half shrinks fast: the input is gone in a small number of steps. Subtracting one shrinks slowly: it takes as many steps as the input is large.
Watch how that single difference changes the final answer, even though the extra work at each call will look similar to a case we have already solved.
Intuition
What move should we make next?
Compare the two shapes side by side:
\[ T(n) = 2T(n/2) + n \qquad \text{versus} \qquad T(n) = T(n-1) + n \]
Same additive work. Completely different recursion.
Before unrolling anything: how many levels does each one have, and which of your moves tells you that?
_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.
Explain it
Discussion prompt
Explain Decision point: this one subtracts instead of divides to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
Same additive work. Completely different recursion.
Hypothesis
Predict first
Unroll T(n) = T(n-1) + n is about to be worked. State your hypothesis first: which rule or definition decides this one, and what is the first move it forces? Then watch whether the example agrees with you.
Correct: Substitute once, then again
Why: Each substitution peels off one call and adds one more term to the running total.
A hypothesis you wrote down is falsifiable; a vague sense of how it will go is not. If the example opens somewhere else, that gap is the thing worth chasing.
Worked example
One recursive call on everything but the last element, plus n units of extra work.
\[ T(n) = T(n-1) + n \]
Substitute once, then again
Why: Each substitution peels off one call and adds one more term to the running total.
\[ T(n) = T(n-2) + (n-1) + n = T(n-3) + (n-2) + (n-1) + n \]
Spot the pattern after k substitutions
Why: Each substitution reduces the argument by 1 and adds the next integer down from n to the accumulated sum.
\[ T(n) = T(n-k) + \big[(n-k+1) + \cdots + n\big] \]
Stop when the argument hits the base case
Why: The argument reaches 1 when k equals n minus 1, leaving a base cost plus the sum of every integer from 2 through n.
\[ T(n) = T(1) + (2 + 3 + \cdots + n) = 1 + \left[\frac{n(n+1)}{2} - 1\right] = \frac{n(n+1)}{2} = \Theta(n^{2}) \]
Verify with n = 4
Why: Direct unrolling gives T(1)=1, T(2)=3, T(3)=6, T(4)=10. The closed form gives n(n+1)/2 = 4 times 5 over 2, which is 10 - an exact match.
Picture it
Animation
Shows: Each line of the worked example "Unroll T(n) = T(n-1) + n", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Direct unrolling gives T(1)=1, T(2)=3, T(3)=6, T(4)=10. The closed form gives n(n+1)/2 = 4 times 5 over 2, which is 10 - an exact match.
Concept
Because the input shrinks by only one each call, it takes a number of calls proportional to n to reach the base case - not a logarithm's worth of calls.
The same-looking linear extra work at each call, multiplied by a number of levels proportional to n instead of a logarithm, is exactly why this total ends up so much bigger.
Analogy
Discussion prompt
Explain Depth is n, not log n, when you subtract instead of divide by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
Because the input shrinks by only one each call, it takes a number of calls proportional to n to reach the base case - not a logarithm's worth of calls.
Step zero
Discussion prompt
Confirm with the recursion tree for T(n) = T(n-1) + n — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Read off the work at each level
Answer:
Worked example
Only one child per node this time - the tree is a single chain, not a branching shape.
\[ T(n) = T(n-1) + n \]
Read off the work at each level
Why: Level 0 is the root, size n, doing n work. Level 1 has one node, size n-1, doing n-1 work. Level 2 does n-2 work, and so on, one less each level.
| level | work at this level |
|---|---|
| 0 | n |
| 1 | n-1 |
| 2 | n-2 |
| ... | ... |
| n-1 | 1 |
Sum every level
Why: The tree has n levels (not log n, since each level only subtracts one), and the level totals are exactly n, n-1, n-2, down to 1.
\[ T(n) = n + (n-1) + \cdots + 1 = \frac{n(n+1)}{2} = \Theta(n^{2}) \]
Verify with n = 4
Why: Adding the level totals directly: 4 + 3 + 2 + 1 equals 10, matching the unrolling result from the previous worked example exactly.
Picture it
Animation
Shows: Each line of the worked example "Confirm with the recursion tree for T(n) = T(n-1) + n", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Adding the level totals directly: 4 + 3 + 2 + 1 equals 10, matching the unrolling result from the previous worked example exactly.
Ranking
Put in order
Put the moves of Verify the closed form for T(n) = 2T(n/2) + n on a new value into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. log2(16) is 4, so the closed form predicts 16 times (4 plus 1), which is 80.
Worked example
Check that the n log n closed form generalizes beyond the single value already checked.
\[ T(n) = n(\log_2 n + 1) \]
Predict T(16) from the closed form
Why: log2(16) is 4, so the closed form predicts 16 times (4 plus 1), which is 80.
\[ T(16) = 16(\log_2 16 + 1) = 16 \times 5 = 80 \]
Compute T(16) directly from the recurrence
Why: Continuing the earlier hand trace: T(2)=4, T(4)=12, T(8)=32, so T(16) = 2 times T(8) plus 16, which is 2 times 32 plus 16.
\[ T(16) = 2(32) + 16 = 80 \]
Verify the two computations match
Why: Both the closed-form prediction and the direct hand computation give 80 for n equal to 16, confirming the formula holds beyond the one value already spot-checked.
Worked example
One recursive call, half the size, but linear (not constant) extra work this time.
\[ T(n) = T\!\left(\frac{n}{2}\right) + n \]
Read off the work at each level
Why: Level 0 is one node of size n doing n work. Level 1 has one node of size n/2 doing n/2 work (only one node exists, since there is only one recursive call). Level 2 does n/4 work, and so on.
| level | work at this level |
|---|---|
| 0 | n |
| 1 | n/2 |
| 2 | n/4 |
| ... | ... |
Sum the geometric series
Why: Unlike every earlier example, the level totals shrink by half each time instead of staying constant. Adding the full series up to the base case gives a total just under twice the root's own work.
\[ T(n) = n + \frac{n}{2} + \frac{n}{4} + \cdots \approx 2n = \Theta(n) \]
Verify with concrete values
Why: With T(1)=1: T(2)=3, T(4)=7, T(8)=15 - each one less than twice n. The pattern 2n minus 1 matches Theta(n), confirming the total is dominated by the root level, not by the number of levels.
Picture it
Animation
Shows: Summing a recursion tree — a rendered Manim animation.
Rendered with Manim.
Takeaway: Level cost times level count, when every level costs the same.
Intuition
Across every example, the same picture explains the answer: how much work sits at each level, and how many levels there are, together decide whether the total is dominated by the root, spread evenly across every level, or piled up in the number of levels itself.
That is the entire idea behind every method in this lesson - the tree just makes it visible.
Pattern
1. Read the code and write the recurrence
Why: Count the recursive calls and the size passed to each, then find everything else the function does - that becomes the extra term.
2. Draw the recursion tree for a guess
Why: Multiply nodes per level by work per node, level by level, and add up all the levels to see the shape of the answer.
3. Unroll to double-check the pattern
Why: Substitute the recurrence into itself a few times, spot the pattern for the k-th substitution, and confirm it matches the tree.
4. Prove the guess with the substitution method
Why: State the guess as an inequality, assume it for the smaller subproblem, substitute into the recurrence, simplify, and verify the base case with a concrete constant.
Real world
Discussion prompt
Outside this lesson: where does Recurrences & Recursion Trees actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of The general recipe for solving a recurrence is doing the work in it.
Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.
Answer:
How to turn a recursive algorithm into a recurrence, then solve it three ways: the recursion-tree method (work per level times number of levels), unrolling by repeated substitution, and the substitution method's proof by induction. Covers both equal and unequal subproblem sizes.
Picture it
Animation
Shows: Four recurrences worth memorising — a rendered Manim animation.
Rendered with Manim.
Takeaway: Recognising these on sight saves most of the work.
Elimination
Eliminate the wrong options
Which recurrence correctly describes this function?
3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.
Survives elimination: A
Why: There are two recursive calls, each on n/2, contributing 2T(n/2). The loop runs n times doing constant work each time, contributing an extra n. Together that is T(n) = 2T(n/2) + n.
Check
Read this function carefully before answering.
function process(n):
if n <= 1:
return
process(n/2)
process(n/2)
for i in 1..n:
doWork(i)Check your understanding
Which recurrence correctly describes this function?
Answer: A
Why: There are two recursive calls, each on n/2, contributing 2T(n/2). The loop runs n times doing constant work each time, contributing an extra n. Together that is T(n) = 2T(n/2) + n.
Prediction
Predict first
Which recurrence correctly describes this function?
Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.
Correct: T(n) = T(n-1) + 1
Why: There is one recursive call, on n-1, and doStep() is a single constant-time operation. That gives T(n) = T(n-1) + 1.
Check
This function shrinks its input differently. Read it carefully.
function walk(n):
if n == 0:
return
doStep()
walk(n-1)Check your understanding
Which recurrence correctly describes this function?
Answer: A
Why: There is one recursive call, on n-1, and doStep() is a single constant-time operation. That gives T(n) = T(n-1) + 1.
Check
Recall the merge-sort recurrence and its recursion tree.
\[ T(n) = 2T\!\left(\frac{n}{2}\right) + n \]
Check your understanding
What is the total work done at level 3 of this recursion tree?
Answer: A
Why: Level 3 has 8 nodes, each of size n/8, each doing n/8 work. Multiplying 8 by n/8 gives n - every level of this tree totals n, no matter how deep.
Check
Recall unrolling T(n) = 2T(n/2) + n, where after k substitutions the pattern is 2 to the k times T of n over 2 to the k, plus k times n.
Check your understanding
After unrolling this recurrence 4 times, which expression matches the pattern?
Answer: A
Why: After k substitutions the coefficient is 2 to the k and the accumulated extra work is k times n. For k = 4: 2 to the 4th is 16, and the accumulated work is 4 times n, giving 16 T(n/16) + 4n.
Check
You are proving T(n) is at most c times n times log2(n) for T(n) = 2T(n/2) + n, by induction.
Check your understanding
In the inductive step, what should you substitute for T(n/2) using the inductive hypothesis?
Answer: A
Why: The inductive hypothesis says the guess holds at the smaller size n/2, so both the coefficient and the logarithm's argument shrink together: T(n/2) is at most c times (n/2) times log2(n/2).
Check
The substitution-method proof needed to simplify log2(n/2) partway through.
Check your understanding
What does log2(n/2) simplify to?
Answer: A
Why: Dividing the argument of a base-2 logarithm by 2 always subtracts exactly 1 from its value, since log2(n/2) = log2(n) - log2(2) = log2(n) - 1.
Commit first
Predict first
What is the order of growth of T(n) = 4T(n/2) + n squared?
Commit to an answer, then rate it — certain, fairly sure, or guessing — and write the rating down before you turn the page.
Correct: Theta(n^2 log n)
Why: Every level of the tree totals n squared, and there are log2(n) plus 1 levels, so the total work is n squared times (log2(n) plus 1), which is Theta(n squared log n).
The rating matters as much as the answer: confident-and-wrong is the combination that survives revision, because nothing about it feels like it needs revisiting.
Check
Recall the recursion tree for T(n) = 4T(n/2) + n squared: every level totals n squared, and there are log2(n) plus 1 levels.
Check your understanding
What is the order of growth of T(n) = 4T(n/2) + n squared?
Answer: A
Why: Every level of the tree totals n squared, and there are log2(n) plus 1 levels, so the total work is n squared times (log2(n) plus 1), which is Theta(n squared log n).
Check
Recall the recursion tree for T(n) = T(n/3) + T(2n/3) + n.
Check your understanding
Which branch determines the total height of this recursion tree?
Answer: A
Why: The branch that keeps two-thirds of n each time shrinks the slowest, so it takes the most steps to reach the base case. The tree is not finished until that slowest branch bottoms out, so it sets the total height.
Prediction
Predict first
How many levels does the recursion tree for T(n) = T(n-1) + n have?
Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.
Correct: n levels
Why: Each call only subtracts 1 from the input, so it takes n steps (from size n down to the base case) to finish - a number of levels proportional to n, not to a logarithm.
Check
Recall the recursion tree for T(n) = T(n-1) + n, which is a single chain rather than a branching tree.
Check your understanding
How many levels does the recursion tree for T(n) = T(n-1) + n have?
Answer: A
Why: Each call only subtracts 1 from the input, so it takes n steps (from size n down to the base case) to finish - a number of levels proportional to n, not to a logarithm.
Elimination
Eliminate the wrong options
What is the order of growth of T(n) = T(n/2) + n?
3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.
Survives elimination: A
Why: The level totals here shrink geometrically (n, n/2, n/4, ...), so the sum is dominated by the root level and adds up to about 2n, which is Theta(n).
Check
Recall the recursion tree for T(n) = T(n/2) + n, where the level totals shrink geometrically instead of staying constant.
Check your understanding
What is the order of growth of T(n) = T(n/2) + n?
Answer: A
Why: The level totals here shrink geometrically (n, n/2, n/4, ...), so the sum is dominated by the root level and adds up to about 2n, which is Theta(n).
Concept
Moves added today:
Moves you reused today:
Move #10 is the level-count half of move #11. You already knew how to count halvings; today you learned to multiply that count by the work each level does.
Full toolkit so far: #1 through #11.
Next session opens with you naming every one of these from memory, before any new material.
Counterexample
Discussion prompt
Move #10 is the level-count half of move #11. You already knew how to count halvings; today you learned to multiply that count by the work each level does.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Answer:
Next session opens with you naming every one of these from memory, before any new material.
Picture it
Animation
Shows: The condition people forget in case three — a rendered Manim animation.
Rendered with Manim.
Takeaway: It almost always holds, and almost nobody checks it.
Connect it up
Draw it
One page, no notation unless you need it: draw how these connect — The general recipe for solving a recurrence · Toolkit check-in: name them before you look · What a recurrence relation is · The general shape of a divide-and-conquer recurrence · Nesting dolls. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.
Recap
You can now turn recursive code into a recurrence, and solve that recurrence with three complementary tools.
| Technique | The one move |
|---|---|
| Recursion tree | Work per level times number of levels, summed |
| Unrolling | Substitute the recurrence into itself until the pattern for step k is clear |
| Substitution method | Guess a bound, then prove it: hypothesis, substitute, simplify, verify |
| Unequal splits | Depth is set by the slowest-shrinking branch, not an assumed average |
Want this taught 1-on-1? Alexander tutors CS3000 Algorithms — $55/session, free consultation.