-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfind-median-data-stream.ts
More file actions
45 lines (41 loc) · 1.48 KB
/
Copy pathfind-median-data-stream.ts
File metadata and controls
45 lines (41 loc) · 1.48 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
import { MinHeap } from "../lib/min-heap.js";
/**
* 295. Find Median from Data Stream (Hard)
* Link: https://leetcode.com/problems/find-median-from-data-stream/
*
* Support addNum(num) to ingest a stream of integers and findMedian() to return
* the median of all values seen so far.
*
* Example:
* addNum(1); addNum(2); findMedian() -> 1.5
* addNum(3); findMedian() -> 2
*
* Approach:
* Two heaps split the data at the median: a max-heap `low` for the smaller
* half and a min-heap `high` for the larger half. Keep their sizes balanced
* (low holds the extra element when the count is odd). The median is low's top
* (odd count) or the average of both tops (even count). The max-heap is a
* MinHeap keyed by the negated value.
*
* Time: addNum O(log n), findMedian O(1).
* Space: O(n)
*/
export class MedianFinder {
private readonly low = new MinHeap<number>((x) => -x); // max-heap of smaller half
private readonly high = new MinHeap<number>((x) => x); // min-heap of larger half
addNum(num: number): void {
// push to low, then shift its max over to high to keep order
this.low.push(num);
this.high.push(this.low.pop()!);
// rebalance so low has equal or one more element than high
if (this.high.size > this.low.size) {
this.low.push(this.high.pop()!);
}
}
findMedian(): number {
if (this.low.size > this.high.size) {
return this.low.peek()!;
}
return (this.low.peek()! + this.high.peek()!) / 2;
}
}