Design Efficient Data Structure for Median Retrieval
Company: Amazon
Role: Data Scientist
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of streaming data structures, median maintenance, and algorithmic complexity in the Coding & Algorithms domain by requiring efficient insertions (O(log n)) and constant-time median queries (O(1)).
Constraints
- 1 <= number of operations <= 5 * 10^4
- -10^5 <= num <= 10^5 for each addNum
- findMedian on an empty structure returns null
- addNum must be O(log n); findMedian must be O(1)
Examples
Input: ([["addNum", 1], ["addNum", 2], ["findMedian"], ["addNum", 3], ["findMedian"]],)
Expected Output: [1.5, 2.0]
Explanation: After adding 1 and 2 the two middle values are 1 and 2, so the median is (1+2)/2 = 1.5. After adding 3 the values are [1,2,3] and the single middle value is 2.0.
Input: ([["addNum", 5], ["findMedian"], ["addNum", 5], ["findMedian"], ["addNum", 5], ["findMedian"]],)
Expected Output: [5.0, 5.0, 5.0]
Explanation: All inserted values are equal, so the median is 5.0 regardless of count, covering the duplicate-values case.
Hints
- Maintain two heaps: a max-heap for the smaller half of the numbers and a min-heap for the larger half.
- After each insert, rebalance so the heaps' sizes differ by at most one — push the offending root across when one heap grows too large.
- If the heaps are equal in size, the median is the average of the two roots; otherwise it is the root of the larger heap. Both are O(1) reads.