Skip to content

Commit 7d3cc69

Browse files
committed
refactor: Find Median From Data Stream
1 parent fff39b4 commit 7d3cc69

File tree

1 file changed

+101
-25
lines changed

1 file changed

+101
-25
lines changed

find-median-from-data-stream/gwbaik9717.js

Lines changed: 101 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,126 @@
1-
// Time complexity: O(n)
1+
// last test case failed
2+
// Time complexity: O(logn)
23
// Space complexity: O(n)
34

5+
class MinHeap {
6+
constructor() {
7+
this.heap = [null];
8+
}
9+
10+
get root() {
11+
if (this.length === 1) {
12+
return null;
13+
}
14+
15+
return this.heap[1];
16+
}
17+
18+
get length() {
19+
return this.heap.length;
20+
}
21+
22+
push(value) {
23+
this.heap.push(value);
24+
25+
let current = this.heap.length - 1;
26+
let parent = Math.floor(current / 2);
27+
28+
while (parent && this.heap[current] < this.heap[parent]) {
29+
[this.heap[current], this.heap[parent]] = [
30+
this.heap[parent],
31+
this.heap[current],
32+
];
33+
current = parent;
34+
parent = Math.floor(current / 2);
35+
}
36+
}
37+
38+
pop() {
39+
if (this.heap.length === 1) {
40+
return null;
41+
}
42+
43+
if (this.heap.length === 2) {
44+
return this.heap.pop();
45+
}
46+
47+
const rv = this.heap[1];
48+
this.heap[1] = this.heap.pop();
49+
50+
let current = 1;
51+
let left = current * 2;
52+
let right = left + 1;
53+
54+
while (
55+
(this.heap[left] && this.heap[current] > this.heap[left]) ||
56+
(this.heap[right] && this.heap[current] > this.heap[right])
57+
) {
58+
if (this.heap[right] && this.heap[right] < this.heap[left]) {
59+
[this.heap[right], this.heap[current]] = [
60+
this.heap[current],
61+
this.heap[right],
62+
];
63+
current = right;
64+
} else {
65+
[this.heap[left], this.heap[current]] = [
66+
this.heap[current],
67+
this.heap[left],
68+
];
69+
current = left;
70+
}
71+
72+
left = current * 2;
73+
right = left + 1;
74+
}
75+
76+
return rv;
77+
}
78+
}
79+
480
var MedianFinder = function () {
5-
this.arr = [];
81+
this.leftMinHeap = new MinHeap();
82+
this.rightMinHeap = new MinHeap();
683
};
784

885
/**
986
* @param {number} num
1087
* @return {void}
1188
*/
1289
MedianFinder.prototype.addNum = function (num) {
13-
if (this.arr.length === 0) {
14-
this.arr.push(num);
15-
return;
16-
}
90+
const rightMinValue = this.rightMinHeap.root;
1791

18-
let left = 0;
19-
let right = this.arr.length - 1;
20-
21-
while (left <= right) {
22-
const mid = Math.floor((left + right) / 2);
23-
24-
if (this.arr[mid] > num) {
25-
right = mid - 1;
26-
continue;
27-
}
92+
if (num >= rightMinValue) {
93+
this.rightMinHeap.push(num);
94+
} else {
95+
this.leftMinHeap.push(num * -1);
96+
}
2897

29-
left = mid + 1;
98+
if (this.rightMinHeap.length - this.leftMinHeap.length > 1) {
99+
const popped = this.rightMinHeap.pop();
100+
this.leftMinHeap.push(popped * -1);
30101
}
31102

32-
// insert in left
33-
const sliced = this.arr.slice(left);
34-
this.arr = [...this.arr.slice(0, left), num, ...sliced];
103+
if (this.leftMinHeap.length - this.rightMinHeap.length > 1) {
104+
const popped = this.leftMinHeap.pop();
105+
this.rightMinHeap.push(popped * -1);
106+
}
35107
};
36108

37109
/**
38110
* @return {number}
39111
*/
40112
MedianFinder.prototype.findMedian = function () {
41-
if (this.arr.length % 2 === 0) {
42-
return (
43-
(this.arr[this.arr.length / 2] + this.arr[this.arr.length / 2 - 1]) / 2
44-
);
113+
const len = this.leftMinHeap.length + this.rightMinHeap.length;
114+
115+
if (len % 2 === 0) {
116+
return (this.leftMinHeap.root * -1 + this.rightMinHeap.root) / 2;
117+
}
118+
119+
if (this.leftMinHeap.length > this.rightMinHeap.length) {
120+
return this.leftMinHeap.root * -1;
45121
}
46122

47-
return this.arr[(this.arr.length - 1) / 2];
123+
return this.rightMinHeap.root;
48124
};
49125

50126
/**

0 commit comments

Comments
 (0)