Finding the median of a data stream can be a challenging problem, especially when you want to do it efficiently as numbers keep streaming in. Instead of storing all numbers and sorting them every time, we can make use of two heaps: a max-heap and a min-heap. Let’s dive into this elegant solution!
The median is the middle number in a sorted list of numbers. Depending on whether we have an odd or even number of elements:
For instance:
Heaps are a type of binary tree that satisfy the heap property. They allow us to efficiently retrieve the largest or smallest elements.
We will maintain two heaps:
Using these two heaps allows us to keep track of the median in O(log n) time for insertion and O(1) time for finding the median.
Here’s how this can be implemented in Java:
import java.util.Collections; import java.util.PriorityQueue; public class MedianFinder { private PriorityQueue<Integer> maxHeap; // max-heap for the left half private PriorityQueue<Integer> minHeap; // min-heap for the right half /** Initialize your data structure here. */ public MedianFinder() { maxHeap = new PriorityQueue<>(Collections.reverseOrder()); minHeap = new PriorityQueue<>(); } public void addNum(int num) { // Add to max-heap (left half) maxHeap.offer(num); // Ensure maxHeap's largest is <= minHeap's smallest if (!minHeap.isEmpty() && maxHeap.peek() > minHeap.peek()) { minHeap.offer(maxHeap.poll()); } // Balance the sizes: maxHeap can have at most one extra element if (maxHeap.size() > minHeap.size() + 1) { minHeap.offer(maxHeap.poll()); } else if (minHeap.size() > maxHeap.size()) { maxHeap.offer(minHeap.poll()); } } public double findMedian() { if (maxHeap.size() > minHeap.size()) { return maxHeap.peek(); } else { return (maxHeap.peek() + minHeap.peek()) / 2.0; } } }
Here's a quick demo of how the MedianFinder
class would work:
public class Main { public static void main(String[] args) { MedianFinder finder = new MedianFinder(); finder.addNum(1); System.out.println(finder.findMedian()); // Output: 1.0 finder.addNum(2); System.out.println(finder.findMedian()); // Output: 1.5 finder.addNum(3); System.out.println(finder.findMedian()); // Output: 2.0 } }
1
, the median is 1.0
.2
, the numbers are [1, 2]
, giving a median of 1.5
.3
, the numbers are [1, 2, 3]
, retrieving the median 2.0
.By utilizing heaps, we achieve a highly efficient solution to the data stream median problem. The dual-heap structure effectively allows us to dynamically maintain the median as new numbers come in.
With a solid understanding of heaps and their application, you're well on your way to tackling similar problems in interviews and coding challenges!
16/11/2024 | DSA
16/11/2024 | DSA
15/11/2024 | DSA
13/10/2024 | DSA
13/10/2024 | DSA
23/09/2024 | DSA
08/12/2024 | DSA
16/11/2024 | DSA
16/11/2024 | DSA
23/09/2024 | DSA
16/11/2024 | DSA