Find Median from Data Stream
Hard
HeapDesign
Problem
Design MedianFinder. addNum(int) adds a value; findMedian() returns the running median.
Example 1
Input: add 1, add 2, find
Output: 1.5
Constraints
- −10⁵ ≤ value ≤ 10⁵
Approach — Heaps / Top-K
This is a Heaps / Top-K problem. The idea: use a heap so the min, max, or top-k element stays reachable in O(log n) per operation. Work through the reference code below line by line, then re-derive it yourself in the editor — that's how the pattern sticks.
Complexity: O(n log k) time.
Solution code
Python
import heapq
class MedianFinder:
def __init__(self):
self.lo = [] # max-heap (negated)
self.hi = [] # min-heap
def addNum(self, num):
heapq.heappush(self.lo, -num)
heapq.heappush(self.hi, -heapq.heappop(self.lo))
if len(self.hi) > len(self.lo):
heapq.heappush(self.lo, -heapq.heappop(self.hi))
def findMedian(self):
if len(self.lo) > len(self.hi):
return -self.lo[0]
return (-self.lo[0] + self.hi[0]) / 2
Java
class MedianFinder {
// Lower half — max-heap. Upper half — min-heap.
// Invariant: low.size() == high.size() or low.size() == high.size() + 1.
// So the median is low.peek() (odd total) or the average of both tops (even).
private final PriorityQueue<Integer> low = new PriorityQueue<>(Comparator.reverseOrder());
private final PriorityQueue<Integer> high = new PriorityQueue<>();
public void addNum(int num) {
// Push to low, then move low's largest into high to keep them balanced.
low.offer(num);
high.offer(low.poll());
// Rebalance if high grew larger than low.
if (high.size() > low.size()) {
low.offer(high.poll());
}
}
public double findMedian() {
if (low.size() > high.size()) {
return low.peek();
}
return (low.peek() + high.peek()) / 2.0;
}
}
class Solution {}
Practice it
Reading a solution isn't the same as being able to write it under pressure. Open this problem in the in-browser editor, hide the solution, and solve it from scratch — your code runs against real test cases instantly.
Solve Find Median from Data Stream interactively → ← All solutions