Median of Medians
Imagine your class needs to pick a team captain fairly. Instead of everyone voting at once (which might be gamed), you try something clever: split into small groups of 5, have each group pick their own captain, then have all the group captains vote among themselves. The winner is a good representative of everyone.
That's exactly what Median of Medians does — and for the same reason. It picks a pivot element that is guaranteed to split the array decently, so no adversary can trick it into \(O(n^2)\) behavior.
The problem with QuickSelect
Randomized QuickSelect is excellent in practice — expected \(O(n)\) with high probability. But if someone hands you carefully crafted input, they can force your random pivot to always be terrible, pushing you to \(O(n^2)\). In security-critical code, or when you need a provable worst-case guarantee, you need something deterministic.
The algorithm step by step
Step 1 — Group into 5s: Split the n elements into groups of exactly 5 (the last group may be smaller). Groups of 5 are the sweet spot — small enough to sort instantly, large enough to give a quality guarantee.
Step 2 — Sort each group and grab the median: Sort each group of 5 with insertion sort (just 7 comparisons max). Take the middle element. You now have ⌈n/5⌉ group medians.
Step 3 — Recursively find the median of those medians: Apply the whole algorithm recursively on just the ⌈n/5⌉ medians. The result is the median of medians — call it M.
Step 4 — Use M as your pivot: Partition the full array around M. Because M is a good pivot (guaranteed 30-70 split), recurse only on the side that contains your target element.
Why is M a good pivot?
M is the median of ⌈n/5⌉ values. At least half of those values are ≥ M. Each such value was the median of a group of 5, so at least 2 elements in that group are also ≥ M. That means at least (n/5)/2 × 2 = n/5 elements in the full array are ≥ M from those groups alone — plus M itself. After careful counting, at least 3n/10 elements are guaranteed to be on each side of M. The partition is always at most 70%-30%, never degenerate.
The recurrence
T(n) = T(n/5) + T(7n/10) + \(O(n)\). The T(n/5) covers finding the median of medians recursively. The T(7n/10) covers the partition recursion on the larger side. The \(O(n)\) covers grouping, sorting groups, and partitioning. This solves to T(n) = \(O(n)\).