Design a data structure that supports addNum(num) and findMedian() efficiently for a stream of numbers.
mf = MedianFinder()
mf.addNum(1) # [1]
mf.addNum(2) # [1, 2]
mf.findMedian() # → 1.5
mf.addNum(3) # [1, 2, 3]
mf.findMedian() # → 2.0
The two-heap trick — one of the most elegant data structure designs:
# After adding [1, 2, 3, 4, 5]:
# max_heap (small half): [3, 1, 2] → top = 3
# min_heap (large half): [4, 5] → top = 4
# Median = 3 (max_heap has 1 more element)
addNum: O(log n), findMedian: O(1). This is a FAANG favorite!
Two heaps: small (max-heap via negation) and large (min-heap). addNum: push to small, then move top of small to large. If large is bigger, move top of large back to small. findMedian: if same size, average both tops. Otherwise, top of small.