☰ All problems

Find Median from Data Stream

HardHeapDesignSorting

A trading dashboard keeps showing the median price move of all trades since the market opened, and it refreshes after every trade. Moves are whole numbers of cents and can be negative. The median of a list is its middle value once sorted; when the list has an even length, it is the average of the two middle values. For example, the median of [-4, 10, 15] is 10, and the median of [-4, 10] is 3.

Implement the MedianFinder class:

  • MedianFinder() starts with no values.
  • addNum(num) records the integer num.
  • findMedian() returns the median of all values recorded so far, as a floating-point number.

The tests call the methods one after another, and findMedian is only called after at least one addNum. Answers within 10^-5 of the expected value are accepted.

Example 1
Input: ["MedianFinder","addNum","findMedian","addNum","addNum","findMedian","addNum","findMedian"]
[[],[12],[],[-3],[7],[],[20],[]]
Output: [null,null,12,null,null,7,null,9.5]

Explanation: With only 12 recorded, the median is 12. After -3 and 7 the sorted moves are [-3, 7, 12], so the median is 7. Adding 20 gives [-3, 7, 12, 20] and a median of (7 + 12) / 2 = 9.5.

Example 2
Input: ["MedianFinder","addNum","addNum","findMedian","addNum","addNum","findMedian"]
[[],[-8],[-2],[],[-2],[-1],[]]
Output: [null,null,null,-5,null,null,-2]

Explanation: The median of -8 and -2 is their average, -5. After -2 and -1 arrive, the sorted moves are [-8, -2, -2, -1], and both middle values are -2.

Constraints

  • Every recorded value fits in a 32-bit signed integer.
  • findMedian is called only after at least one value has been recorded.
  • A test makes at most 50,000 calls in total.

Follow-up: Suppose almost every price move falls between 0 and 100 cents, with only rare outliers outside that band. How could you use that to make both operations run in constant time, and how would you handle the outliers?

πŸ’‘ Hint 1

Keeping a sorted array makes findMedian O(1) but each insertion O(n). You only ever need the one or two values in the middle.

πŸ’‘ Hint 2

Split the numbers into a lower half and an upper half. The median depends only on the largest value of the lower half and the smallest of the upper half.

πŸ’‘ Hint 3

Store the lower half in a max-heap and the upper half in a min-heap, and rebalance after each insert so the lower half has the same size as the upper half or one more. (In Java, widen to long before adding the two tops: two large ints can overflow.)

class MedianFinder {
  constructor() {

  }

  /** @param {number} num */
  addNum(num) {

  }

  /** @return {number} */
  findMedian() {

  }
}
Ctrl/⌘ + ' run · Ctrl/⌘ + Enter submit
esc