Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
For example,[2,3,4]
, the median is 3
[2,3]
, the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
Example:
addNum(1) addNum(2) findMedian() -> 1.5 addNum(3) findMedian() -> 2
Follow up:
use std::cmp::Reverse;
use std::collections::BinaryHeap;
#[derive(Default)]
struct MedianFinder {
lo: BinaryHeap<i32>,
hi: BinaryHeap<Reverse<i32>>,
}
impl MedianFinder {
fn new() -> Self {
MedianFinder::default()
}
fn add_num(&mut self, num: i32) {
self.hi.push(Reverse(num));
let smallest = self.hi.pop().unwrap().0;
self.lo.push(smallest);
if self.lo.len() > self.hi.len() + 1 {
self.hi.push(Reverse(self.lo.pop().unwrap()));
}
}
fn find_median(&self) -> f64 {
if (self.lo.len() + self.hi.len()) % 2 == 0 {
(*self.lo.peek().unwrap() + self.hi.peek().unwrap().0) as f64 / 2.0
} else {
*self.lo.peek().unwrap() as f64
}
}
}
#[test]
fn test() {
use assert_approx_eq::assert_approx_eq;
let mut obj = MedianFinder::new();
obj.add_num(1);
obj.add_num(2);
assert_approx_eq!(obj.find_median(), 1.5);
obj.add_num(3);
assert_approx_eq!(obj.find_median(), 2.0);
}