|
1 | 1 | #![allow(dead_code)]
|
2 |
| -struct MedianFinder {} |
| 2 | +use std::cmp::Reverse; |
| 3 | +use std::collections::BinaryHeap; |
| 4 | + |
| 5 | +pub struct MedianFinder { |
| 6 | + max_heap: BinaryHeap<i32>, |
| 7 | + min_heap: BinaryHeap<Reverse<i32>>, |
| 8 | +} |
3 | 9 |
|
4 |
| -/** |
5 |
| - * `&self` means the method takes an immutable reference. |
6 |
| - * If you need a mutable reference, change it to `&mut self` instead. |
7 |
| - */ |
8 | 10 | impl MedianFinder {
|
9 |
| - fn new() -> Self { |
10 |
| - todo!() |
| 11 | + pub fn new() -> Self { |
| 12 | + MedianFinder { |
| 13 | + max_heap: BinaryHeap::new(), |
| 14 | + min_heap: BinaryHeap::new(), |
| 15 | + } |
11 | 16 | }
|
12 | 17 |
|
13 |
| - fn add_num(&self, num: i32) { |
14 |
| - todo!() |
| 18 | + pub fn add_num(&mut self, num: i32) { |
| 19 | + self.max_heap.push(num); |
| 20 | + if let Some(max_heap_top) = self.max_heap.pop() { |
| 21 | + self.min_heap.push(Reverse(max_heap_top)); |
| 22 | + } |
| 23 | + if self.max_heap.len() < self.min_heap.len() { |
| 24 | + if let Some(Reverse(min_heap_top)) = self.min_heap.pop() { |
| 25 | + self.max_heap.push(min_heap_top); |
| 26 | + } |
| 27 | + } |
15 | 28 | }
|
16 | 29 |
|
17 |
| - fn find_median(&self) -> f64 { |
18 |
| - todo!() |
| 30 | + pub fn find_median(&self) -> f64 { |
| 31 | + if self.max_heap.len() > self.min_heap.len() { |
| 32 | + *self.max_heap.peek().unwrap() as f64 |
| 33 | + } else { |
| 34 | + (*self.max_heap.peek().unwrap() as f64 + self.min_heap.peek().unwrap().0 as f64) / 2.0 |
| 35 | + } |
19 | 36 | }
|
20 | 37 | }
|
| 38 | + |
| 39 | +#[test] |
| 40 | +fn test_find_median_from_data_stream() { |
| 41 | + let mut median_finder = MedianFinder::new(); |
| 42 | + median_finder.add_num(1); |
| 43 | + median_finder.add_num(2); |
| 44 | + assert_eq!(median_finder.find_median(), 1.5); |
| 45 | + median_finder.add_num(3); |
| 46 | + assert_eq!(median_finder.find_median(), 2.0); |
| 47 | +} |
0 commit comments