-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paths0295_find_median_from_data_stream.rs
More file actions
91 lines (81 loc) · 2.32 KB
/
s0295_find_median_from_data_stream.rs
File metadata and controls
91 lines (81 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#![allow(unused)]
use std::collections::BinaryHeap;
use std::cmp::Reverse;
use std::cmp::Ordering;
struct MedianFinder {
lo: BinaryHeap<i32>,
hi: BinaryHeap<Reverse<i32>>,
}
// https://leetcode.com/problems/find-median-from-data-stream/
// reference: https://leetcode.com/problems/find-median-from-data-stream/discuss/488917/Rust-20ms-10.9MB-beat-100
//
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl MedianFinder {
/** initialize your data structure here. */
fn new() -> Self {
Self{
lo: BinaryHeap::new(),
hi: BinaryHeap::new(),
}
}
fn add_num(&mut self, num: i32) {
match (self.lo.peek(), self.hi.peek()) {
(None, Some(_)) => self.hi.push(Reverse(num)),
(None, None) => self.lo.push(num),
(Some(_), Some(Reverse(h))) if num >= *h => self.hi.push(Reverse(num)),
(Some(_), Some(_)) => self.lo.push(num),
(Some(_), None) => self.lo.push(num),
};
match self.lo.len().cmp(&self.hi.len()) {
Ordering::Greater => {
if let Some(l) = self.lo.pop() {
self.hi.push(Reverse(l));
}
}
Ordering::Less => {
if let Some(Reverse(h)) = self.hi.pop() {
self.lo.push(h);
}
}
Ordering::Equal => {}
}
}
fn find_median(&self) -> f64 {
match (self.lo.peek(), self.hi.peek()) {
(Some(left), Some(Reverse(right))) => {
if (self.lo.len() + self.hi.len()) % 2 == 0 {
(left + right) as f64 / 2.0
} else if self.lo.len() > self.hi.len() {
*left as f64
} else {
*right as f64
}
}
(Some(l), None) => *l as f64,
(None, Some(Reverse(h))) => *h as f64,
(None, None) => 0.0
}
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* let obj = MedianFinder::new();
* obj.add_num(num);
* let ret_2: f64 = obj.find_median();
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_239() {
let mut mf = MedianFinder::new();
mf.add_num(1);
mf.add_num(2);
assert_eq!(mf.find_median(), 1.5);
mf.add_num(3);
assert_eq!(mf.find_median(), 2.0);
}
}