C++ - Find Median in a Stream (Running Median Problem)
Problem Statement
You are given a stream of integers.
You need to find the median after each insertion of a number into the stream.
Example 1
Input: [5, 15, 1, 3]
Output: [5, 10, 5, 4]
Explanation:
- After inserting **5**, median = **5**
- After inserting **15**, median = **(5+15)/2 = 10**
- After inserting **1**, median = **5**
- After inserting **3**, median = **(3+5)/2 = 4**
Efficient Approach: Using Two Heaps (Min-Heap & Max-Heap)
Max-Heap (left) → Stores the smaller half of numbers.
Min-Heap (right) → Stores the larger half of numbers.
Balancing condition:
If max-heap has more than 1 extra element than min-heap, move a top element to min-heap.
If the min-heap has more elements, move a top element to the max-heap.
Median Calculation:
If heaps are equal → Median is (max-heap top + min-heap top) / 2.
Else → Median is max-heap top (as max-heap will have one extra element).
Code Implementation
#include <iostream>
#include <queue>
using namespace std;
class MedianFinder {
private:
priority_queue<int> maxHeap; // Max-Heap (left half)
priority_queue<int, vector<int>, greater<int>> minHeap; // Min-Heap (right half)
public:
void addNum(int num) {
if (maxHeap.empty() || num <= maxHeap.top()) {
maxHeap.push(num);
} else {
minHeap.push(num);
}
// Balance the heaps
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.push(maxHeap.top());
maxHeap.pop();
} else if (minHeap.size() > maxHeap.size()) {
maxHeap.push(minHeap.top());
minHeap.pop();
}
}
double findMedian() {
if (maxHeap.size() == minHeap.size()) {
return (maxHeap.top() + minHeap.top()) / 2.0;
}
return maxHeap.top();
}
};
int main() {
MedianFinder medianFinder;
int arr[] = {5, 15, 1, 3};
for (int num : arr) {
medianFinder.addNum(num);
cout << "Median after inserting " << num << ": " << medianFinder.findMedian() << endl;
}
return 0;
}
Explanation
Step-by-Step Execution for Input [5, 15, 1, 3]
Inserted Number Max-Heap (Left) Min-Heap (Right) Median
5 [5] [] 5
15 [5] [15] (5+15)/2 = 10
1 [1, 5] [15] 5
3 [3, 1] [5, 15] (3+5)/2 = 4
Time Complexity Analysis
Operation Complexity
Insertion O(log N) (heap insertion)
Finding Median O(1) (reading top element)
Overall Complexity O(N log N) for N elements
Alternative Approach: Using Multiset (Balanced BST)
Instead of heaps, we can use a Balanced BST (std::multiset) with iterators.
Code using std::multiset
#include <iostream>
#include <set>
using namespace std;
class MedianFinder {
private:
multiset<int> elements;
multiset<int>::iterator mid;
public:
MedianFinder() : mid(elements.end()) {}
void addNum(int num) {
elements.insert(num);
if (elements.size() == 1) {
mid = elements.begin();
} else if (num < *mid) {
if (elements.size() % 2 == 0) mid--;
} else {
if (elements.size() % 2 == 1) mid++;
}
}
double findMedian() {
int n = elements.size();
if (n % 2 == 0) {
return (*mid + *next(mid)) / 2.0;
}
return *mid;
}
};
int main() {
MedianFinder medianFinder;
int arr[] = {5, 15, 1, 3};
for (int num : arr) {
medianFinder.addNum(num);
cout << "Median after inserting " << num << ": " << medianFinder.findMedian() << endl;
}
return 0;
}