Find Median From Data Stream
Problem
The median is the middle value in a sorted list of integers. For lists of even length, there is no middle value, so the median is the mean of the two middle values.
For example:
- For arr = [1,2,3], the median is 2.
- For arr = [1,2], the median is (1 + 2) / 2 = 1.5
Implement the MedianFinder class:
MedianFinder()initializes the MedianFinder object.void addNum(int num)adds the integer num from the data stream to the data structure.double findMedian()returns the median of all elements so far.
Examples
Example 1:
Input:
["MedianFinder", "addNum", "1", "findMedian", "addNum", "3" "findMedian", "addNum", "2", "findMedian"]
Output:
[null, null, 1.0, null, 2.0, null, 2.0]
Explanation:
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.findMedian(); // return 1.0
medianFinder.addNum(3); // arr = [1, 3]
medianFinder.findMedian(); // return 2.0
medianFinder.addNum(2); // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0
Constraints
- -100,000 <= num <= 100,000
findMedianwill only be called after adding at least one integer to the data structure.
You should aim for a solution with O(log n) time for addNum(), O(1) time for findMedian(), and O(n) space, where n is the current number of elements.
Solution
class MedianFinder {
std::priority_queue<int, std::vector<int>, std::less<int>> max_heap;
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
public:
MedianFinder() = default;
void addNum(int num) {
// If num is greater than min_heap top, add to min heap
if (!min_heap.empty() && num > min_heap.top()) {
min_heap.push(num);
} else {
max_heap.push(num);
}
// Rebalance if size difference is larger than 1
auto max_size = std::max(min_heap.size(), max_heap.size());
auto min_size = std::min(min_heap.size(), max_heap.size()
if (max_size - min_size) > 1) {
if (min_heap.size() > max_heap.size()) {
max_heap.push(min_heap.top());
min_heap.pop();
} else {
min_heap.push(max_heap.top());
max_heap.pop();
}
}
}
double findMedian() {
if (min_heap.size() == max_heap.size()) {
return static_cast<double>(min_heap.top() + max_heap.top()) / 2.0;
}
return static_cast<double>(
min_heap.size() > max_heap.size() ? min_heap.top() : max_heap.top()
);
}
};