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)\).