Unit 1 · Algorithms · Lesson 18 of 24
Divide and conquer
Step 1: Learn the ideas
- Split, solve, combine
- Writing recurrences from code
- Recursion trees
- Master theorem intuition
- Merge sort and counting during the merge
- Quicksort and partition schemes
- Quickselect: expected versus worst case
- Median of medians (awareness)
- Exponentiation by squaring
- Overlapping subproblems: when to switch to DP
Why it matters
Divide and conquer is the reasoning behind the fastest general sorting and selection algorithms and many tree algorithms, and it is how you justify a bound like O(n log n) instead of recalling it. Questions in this area check whether you can write the recurrence for your own recursive code, whether you distinguish expected from worst-case time, and whether you can augment a known algorithm (counting during a merge) instead of starting from scratch. The same structure appears in parallel and distributed computation, where independent parts are processed separately and partial results are combined, as in external sorting and map-reduce style aggregation.
Core ideas
Shape and correctness. Split the input into a parts of size about n/b, solve each recursively and combine in f(n) time: T(n) = a T(n/b) + f(n). Correctness is an induction on input size: assume the recursive calls are correct, show the combine step produces a correct result, and check the base cases.
Recursion trees and master-theorem intuition. Level i has a^i subproblems of size n/b^i, so it does a^i f(n/b^i) work. Compare f(n) with n^(log_b a), the number of leaves:
- If f grows polynomially slower, the leaves dominate:
T(n) = Θ(n^(log_b a)). Example:8T(n/2) + n^2gives Θ(n^3). - If they match, every level costs about the same and there are about log n levels:
Θ(n^(log_b a) log n). Merge sort,2T(n/2) + n, gives Θ(n log n). - If f grows polynomially faster (and satisfies a regularity condition), the root dominates: Θ(f(n)). Example:
2T(n/2) + n^2gives Θ(n^2).
Recurrences that shrink by subtraction rather than by a factor, such as T(n) = T(n-1) + n, are outside the theorem; they sum to Θ(n^2). Binary search, T(n) = T(n/2) + 1, is the balanced case with a = 1: Θ(log n). A traversal that visits both halves with constant extra work, 2T(n/2) + 1, is Θ(n).
Merge sort and counting. During a merge, when an element is taken from the right half, every element still waiting in the left half is larger than it. So cross pairs that satisfy an order condition (inversions, smaller elements to the right) can be counted in bulk in the same linear pass, keeping O(n log n) overall. Track original indices when counts must be reported per element.
Quicksort and quickselect. Partitioning around a pivot puts smaller elements left and larger elements right, and the pivot lands in its final position. Quicksort recurses on both sides; quickselect recurses only into the side containing position k. With a uniformly random pivot, the expected size of the side kept shrinks by a constant factor, so the expected total work is a geometric series: O(n). The worst case is still O(n^2), for example a first-element pivot on sorted input. Median of medians guarantees O(n) worst case with larger constants. Random pivots do not rescue a two-way partition that sends all keys equal to the pivot to one side: an array of identical keys stays quadratic, so use three-way partitioning.
Exponentiation by squaring. x^n = (x^(n/2))^2, times x when n is odd: T(n) = T(n/2) + O(1), so O(log n) multiplications. Handle n < 0 by inverting x, and remember that negating the most negative 32-bit integer overflows in fixed-width languages.
Divide and conquer versus DP. If the same subproblem recurs across branches, as in naive Fibonacci, plain recursion repeats work exponentially; caching results turns it into dynamic programming. Divide and conquer fits when subproblems are disjoint.
Common misconceptions
- "Quickselect is O(n)." It is expected O(n) with random pivots and O(n^2) in the worst case; say both, and mention median of medians for a worst-case guarantee.
- "Any recursion that halves the input is O(log n)." Halving with linear combine work is O(n log n), and recursing into both halves with constant work is O(n). Write the recurrence.
- "The master theorem solves every recurrence." It needs equal-sized subproblems shrinking by a constant factor; uneven splits and subtractive recurrences need recursion trees or substitution.
- "Merge sort needs O(n log n) extra memory." One auxiliary buffer of size n suffices, plus O(log n) stack for arrays.
- "Random pivots make quicksort immune to bad inputs." They make unlucky splits improbable for any input order, but many equal keys still need three-way partitioning.
How to approach it
Before coding, state the split, the recursive calls and the combine step, and write T(n). When asked for the k-th largest element, offer a size-k heap (O(n log k)) and quickselect (expected O(n)), then say which you will implement and why. For counting problems over pairs, ask whether a merge pass can count the cross pairs. Test recursive code on sizes 0, 1 and 2 and on duplicates. Mid and senior interviewers may ask how to make the worst case robust or how the approach parallelizes; independence of subproblems is the reason it does.
Suggested order
- 1Read MIT 6.006 Lecture 3 (Sorting) for merge sort and the three ways it solves recurrences (substitution, recurrence tree, master theorem); Recitation 3 states the master theorem.
- 2Read Erickson Ch. 1 (Recursion), the mergesort, quicksort and linear-time selection sections; use his lecture notes on solving recurrences only if recursion trees still feel shaky.
- 3Read MIT 6.046J Lecture 2 for median finding (median of medians) and skim Lecture 6 for the expected-time analysis of randomized quicksort; focus on the arguments rather than the algebra.
- 4Implement merge sort and random-pivot quickselect from memory, testing on empty, single-element, all-equal and already sorted arrays.
- 5Solve Sort an Array, Pow(x, n), and Kth Largest Element in an Array (both with a heap and with quickselect).
- 6Solve Merge k Sorted Lists by pairwise merging and write its recurrence, then Construct Binary Tree from Preorder and Inorder Traversal; keep Median of Two Sorted Arrays and Count of Smaller Numbers After Self as stretch items.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
MIT 6.006 Introduction to Algorithms (Spring 2020)Start here
MIT OpenCourseWareSection: Lecture 3: Sorting
Merge sort and solving recurrences by substitution, recurrence trees and the master theorem (stated in Recitation 3).
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms (Jeff Erickson) with companion lecture notesStart here
Jeff Erickson, University of Illinois Urbana-ChampaignSection: Ch. 1: Recursion
Mergesort and quicksort with correctness and analysis, recursion trees, quickselect with good pivots (median of medians) and fast exponentiation.
Open(opens in a new tab)Link responded, 5 Oct 2026MIT 6.046J Design and Analysis of Algorithms (Spring 2015)
MIT OpenCourseWareSection: Lecture 2: Divide & Conquer: Convex Hull, Median Finding
Median of medians and a recurrence the master theorem cannot solve directly; Lecture 6 on the same index analyzes randomized quicksort.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
For each problem, write the recurrence before coding and solve it. Implement Kth Largest Element twice (heap, then quickselect) and explain when you would choose each. Median of Two Sorted Arrays and Count of Smaller Numbers After Self are stretch items: the first discards half of the remaining candidates per step, the second augments the merge step instead of starting over.
- Sort an ArrayLeetCode(opens in a new tab)Not attemptedLeetCode
- Pow(x, n)LeetCode(opens in a new tab)Not attemptedLeetCode
- Kth Largest Element in an ArrayLeetCode(opens in a new tab)Not attemptedLeetCode
- Merge k Sorted ListsLeetCode(opens in a new tab)Not attemptedLeetCode
- Construct Binary Tree from Preorder and Inorder TraversalLeetCode(opens in a new tab)Not attemptedLeetCode
- Median of Two Sorted ArraysLeetCode(opens in a new tab)Not attemptedLeetCode
- Count of Smaller Numbers After SelfLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1What recurrence describes merge sort, and how does the recursion tree show Θ(n log n)?
- Question 2Which term dominates in T(n) = 3T(n/2) + n, and what is the solution?
- Question 3Why is quickselect expected linear, and which input makes a fixed-pivot version quadratic?
- Question 4How do you count cross pairs during a merge without increasing the asymptotic cost?
- Question 5What goes wrong in fast exponentiation with the most negative 32-bit exponent?
- Question 6What distinguishes the subproblems of divide and conquer from those of dynamic programming?
You’re done when you can
- Solve five given recurrences, including one subtractive and one uneven split, by recursion tree in under 15 minutes without notes.
- Implement random-pivot quickselect in under 15 minutes and state its expected and worst-case running times with a one-sentence reason for each.
- Implement merge sort, extend it to count inversions, and check it against a brute-force O(n^2) counter on random arrays.
- Explain when divide and conquer turns into dynamic programming.


