What if you could instantly know the middle value of a never-ending list without sorting it every time?
Why Median of Data Stream Using Two Heaps in DSA Rust?
Imagine you are tracking the middle value of a growing list of numbers, like recording the median temperature every hour. Doing this by sorting the entire list every time a new number arrives is like rearranging your entire bookshelf after adding each new book--slow and tiring.
Sorting the whole list after each new number is very slow and wastes time. It also uses a lot of memory and can cause mistakes if you lose track of the order. This makes it hard to get the middle value quickly when the list is large or keeps growing.
Using two heaps (special trees) splits the numbers into two groups: one for smaller half and one for bigger half. This way, you only keep track of the middle values at the top of these heaps. Adding a new number and finding the median becomes fast and easy, like having two neat piles where you only look at the top book.
let mut numbers = vec![]; numbers.push(new_number); numbers.sort(); let median = numbers[numbers.len() / 2];
use std::collections::BinaryHeap;
let mut max_heap = BinaryHeap::new();
let mut min_heap = BinaryHeap::new();
// Add number to one of the heaps and rebalance
// Median is top of heaps depending on sizesThis method lets you find the median instantly as new numbers come in, even if the list is very long or never stops growing.
Streaming apps use this to show the middle rating of songs as users keep rating them live, without waiting to sort all ratings every time.
Manual sorting after each new number is slow and inefficient.
Two heaps keep smaller and larger halves separately for quick median access.
This approach handles continuous data streams efficiently and accurately.
Practice
Solution
Step 1: Understand the role of two heaps
The max-heap stores the smaller half of the numbers, and the min-heap stores the larger half.Step 2: How this helps find the median
Balancing these heaps allows quick access to the middle values, enabling efficient median calculation.Final Answer:
To efficiently find the median by balancing smaller and larger halves of the data -> Option CQuick Check:
Two heaps balance halves = median found fast [OK]
- Thinking heaps sort all data fully
- Using only one heap for median
- Ignoring balancing heaps after insertion
Solution
Step 1: Identify Rust's heap implementation
Rust's standard library provides BinaryHeap which is a max-heap by default.Step 2: Using Reverse wrapper for min-heap
To create a min-heap, BinaryHeap with Reverse wrapper is used; for max-heap, BinaryHeap alone suffices.Final Answer:
BinaryHeap (max-heap by default) -> Option AQuick Check:
BinaryHeap = max-heap in Rust [OK]
- Using Vec and sorting every time (slow)
- Confusing HashMap with heap
- Using LinkedList which is not a heap
Solution
Step 1: Insert 5 and find median
Max-heap: [5], Min-heap: [], median = 5Step 2: Insert 15 and balance heaps
Max-heap: [5], Min-heap: [15], median = (5+15)/2 = 10Step 3: Insert 1 and rebalance
Max-heap: [5,1], Min-heap: [15], median = 5Step 4: Insert 3 and rebalance
Max-heap: [3,1], Min-heap: [5,15], median = (3+5)/2 = 4Final Answer:
4 -> Option DQuick Check:
Median after 4 inserts = 4 [OK]
- Not balancing heaps after insertion
- Taking median as last inserted number
- Incorrect average calculation for even count
if num <= *max_heap.peek().unwrap() {
max_heap.push(num);
} else {
min_heap.push(num);
}
if max_heap.len() > min_heap.len() + 1 {
let val = max_heap.pop().unwrap();
min_heap.push(val);
} else if min_heap.len() > max_heap.len() {
let val = min_heap.pop().unwrap();
max_heap.push(val);
}Solution
Step 1: Analyze peek() usage on max_heap
Calling peek() on an empty max_heap causes unwrap() panic because there is no element.Step 2: Identify missing empty check
Code should check if max_heap is empty before peek() to avoid runtime error.Final Answer:
Missing check for empty max_heap before peek() causing panic -> Option AQuick Check:
peek() on empty heap = panic without check [OK]
- Assuming heaps always have elements before peek()
- Confusing which heap to pop from when balancing
- Ignoring unwrap() panic possibility
Solution
Step 1: Understand problem with duplicates and removals
Heaps alone cannot remove arbitrary elements efficiently, especially duplicates.Step 2: Use hash map for counts and lazy removal
Track counts of elements in a hash map and mark elements for removal without immediate heap deletion.Step 3: Clean heaps lazily during median calculation
Remove invalid elements from heap tops lazily to maintain correct median.Final Answer:
Use two heaps plus a hash map to track counts and lazy removal of elements -> Option BQuick Check:
Heaps + hash map = efficient median with removals [OK]
- Trying to remove elements directly from heaps
- Ignoring duplicates in median calculation
- Using only sorting which is inefficient
Ready to prove it?
Pass the test and this pattern moves unknown
