📖 Scenario: Imagine you are building a system that receives a continuous stream of numbers, like temperatures from sensors. You want to quickly find the middle value (median) of all numbers received so far at any time.
🎯 Goal: Build a program in Go that uses two heaps (a max heap and a min heap) to efficiently find the median of a stream of numbers as they arrive.
📋 What You'll Learn
Create two heaps: a max heap for the lower half of numbers and a min heap for the upper half.
Add numbers to the heaps while keeping their sizes balanced.
Calculate the median based on the sizes and top elements of the heaps.
Print the median after inserting each number.
💡 Why This Matters
🌍 Real World
Finding the median in real-time data streams like sensor readings, stock prices, or user ratings.
💼 Career
This technique is useful for software engineers working on data processing, real-time analytics, or financial applications.
Progress0 / 4 steps
1
Create two heaps for storing numbers
Create two variables called low and high as slices of integers. These will represent the max heap and min heap respectively.
DSA Go
Hint
Use slices to represent heaps initially. We will add heap operations later.
2
Add a helper function to balance the heaps
Add a function called balanceHeaps that keeps the size difference between low and high at most 1 by moving elements between them.
DSA Go
Hint
Check the lengths of both slices and move the last element from the bigger heap to the smaller heap.
3
Add numbers and maintain heap properties
Add a function called addNumber that takes an integer num. If low is empty or num is less than or equal to the last element of low, append num to low. Otherwise, append it to high. Then call balanceHeaps().
DSA Go
Hint
Compare num with the last element of low to decide where to add it.
4
Print the median after each insertion
In main, add these numbers in order: 5, 15, 1, 3 by calling addNumber. After each addition, print the median. If low and high have the same length, print the average of their last elements as a float. Otherwise, print the last element of the bigger heap as a float.
DSA Go
Hint
After each addNumber call, check the sizes of low and high and print the median accordingly.
Practice
(1/5)
1. What is the main purpose of using two heaps (a max-heap and a min-heap) in finding the median of a data stream?
easy
A. To store all numbers in a single data structure
B. To sort all numbers in ascending order
C. To efficiently keep track of the lower half and upper half of the numbers separately
D. To find the maximum number in the data stream
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: Explain how this helps find the median
By balancing these heaps, the median is either the top of one heap or the average of the tops of both heaps.
Final Answer:
To efficiently keep track of the lower half and upper half of the numbers separately -> Option C
Quick Check:
Two heaps split data halves = A [OK]
Hint: Two heaps split data halves for median [OK]
Common Mistakes:
Thinking heaps sort all numbers fully
Using one heap only
Confusing max-heap and min-heap roles
2. Which of the following Go code snippets correctly initializes a max-heap and a min-heap for integers using container/heap package?
easy
A. maxHeap := &IntMaxHeap{}; minHeap := &IntMinHeap{}
B. maxHeap := heap.New(IntMaxHeap{}); minHeap := heap.New(IntMinHeap{})
C. maxHeap := &IntMinHeap{}; minHeap := &IntMaxHeap{}
D. maxHeap := make([]int, 0); minHeap := make([]int, 0)
Solution
Step 1: Recognize heap initialization in Go
Heaps are initialized as pointers to custom heap types that implement heap.Interface.
Step 2: Identify correct syntax
Using &IntMaxHeap{} and &IntMinHeap{} creates pointers to heap structs ready for heap operations.
Final Answer:
maxHeap := &IntMaxHeap{}; minHeap := &IntMinHeap{} -> Option A
Quick Check:
Pointer to heap struct = A [OK]
Hint: Use pointers to heap structs for container/heap [OK]
Common Mistakes:
Using heap.New which does not exist
Swapping max-heap and min-heap types
Initializing as slices without heap.Interface
3. Given the following sequence of numbers inserted into the data stream: 5, 15, 1, 3, what is the median after all insertions using two heaps?
Heaps sizes equal (2 each). Median = average of maxHeap top (3) and minHeap top (5) = (3+5)/2 = 4.
Final Answer:
4 -> Option D
Quick Check:
Median = (3+5)/2 = 4 [OK]
Hint: Median is average of two heap tops if sizes equal [OK]
Common Mistakes:
Taking median as maxHeap top only
Not balancing heaps after insertion
Calculating median as sum instead of average
4. In the following Go code snippet for median calculation, what is the bug?
func addNum(num int) {
if maxHeap.Len() == 0 || num <= (*maxHeap)[0] {
heap.Push(maxHeap, num)
} else {
heap.Push(minHeap, num)
}
if maxHeap.Len() > minHeap.Len()+1 {
heap.Push(minHeap, heap.Pop(maxHeap))
} else if minHeap.Len() > maxHeap.Len() {
heap.Push(maxHeap, heap.Pop(minHeap))
}
}
medium
A. Heaps are not balanced after insertion
B. Comparison operator should be < instead of <=
C. heap.Pop returns interface{}, needs type assertion before Push
D. maxHeap and minHeap are swapped in conditions
Solution
Step 1: Analyze balancing logic
The first condition correctly balances when maxHeap is too large (> minHeap.Len()+1). But the second condition checks minHeap.Len() > maxHeap.Len(), which triggers rebalance correctly when minHeap is larger.
Step 2: Why heaps are not balanced
Original code used > maxHeap.Len() + 1 which fails to rebalance when minHeap is exactly one larger. Changing to > maxHeap.Len() fixes this.
Final Answer:
Heaps are not balanced after insertion -> Option A
Quick Check:
minHeap balance: > max.Len() [OK]
Hint: minHeap balance when len(min) > len(max) [OK]
Common Mistakes:
Using +1 symmetrically for both balance conditions
Wrong size difference in minHeap check
Not balancing after every insertion
5. You want to find the median of a large data stream where numbers can be negative, zero, or positive. Which approach using two heaps ensures correct median calculation even with duplicates and negative values?
hard
A. Use a single max-heap and pop elements until median is found
B. Use a max-heap for lower half and min-heap for upper half, balance sizes, and calculate median from tops
C. Sort all numbers in an array and pick middle element(s) each time
D. Use two min-heaps and merge their outputs to find median