Skip to content

Commit 54e8c90

Browse files
authored
Update 295-find-median-from-data-stream.js
1 parent ff75ccd commit 54e8c90

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

295-find-median-from-data-stream.js

+104
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,107 @@ MedianFinder.prototype.findMedian = function() {
3838
* obj.addNum(num)
3939
* var param_2 = obj.findMedian()
4040
*/
41+
42+
// another
43+
44+
/**
45+
* initialize your data structure here.
46+
*/
47+
const MedianFinder = function() {
48+
this.minPQ = new PriorityQueue()
49+
this.maxPQ = new PriorityQueue((a, b) => a < b)
50+
};
51+
52+
/**
53+
* @param {number} num
54+
* @return {void}
55+
*/
56+
MedianFinder.prototype.addNum = function(num) {
57+
this.minPQ.push(num)
58+
this.maxPQ.push(this.minPQ.pop())
59+
if(this.minPQ.size() < this.maxPQ.size()) {
60+
this.minPQ.push(this.maxPQ.pop())
61+
}
62+
};
63+
64+
/**
65+
* @return {number}
66+
*/
67+
MedianFinder.prototype.findMedian = function() {
68+
if(this.minPQ.size() > this.maxPQ.size()) return this.minPQ.peek()
69+
else return (this.minPQ.peek() + this.maxPQ.peek()) / 2
70+
};
71+
72+
/**
73+
* Your MedianFinder object will be instantiated and called as such:
74+
* var obj = new MedianFinder()
75+
* obj.addNum(num)
76+
* var param_2 = obj.findMedian()
77+
*/
78+
class PriorityQueue {
79+
constructor(comparator = (a, b) => a > b) {
80+
this.heap = []
81+
this.top = 0
82+
this.comparator = comparator
83+
}
84+
size() {
85+
return this.heap.length
86+
}
87+
isEmpty() {
88+
return this.size() === 0
89+
}
90+
peek() {
91+
return this.heap[this.top]
92+
}
93+
push(...values) {
94+
values.forEach((value) => {
95+
this.heap.push(value)
96+
this.siftUp()
97+
})
98+
return this.size()
99+
}
100+
pop() {
101+
const poppedValue = this.peek()
102+
const bottom = this.size() - 1
103+
if (bottom > this.top) {
104+
this.swap(this.top, bottom)
105+
}
106+
this.heap.pop()
107+
this.siftDown()
108+
return poppedValue
109+
}
110+
replace(value) {
111+
const replacedValue = this.peek()
112+
this.heap[this.top] = value
113+
this.siftDown()
114+
return replacedValue
115+
}
116+
117+
parent = (i) => ((i + 1) >>> 1) - 1
118+
left = (i) => (i << 1) + 1
119+
right = (i) => (i + 1) << 1
120+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
121+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
122+
siftUp = () => {
123+
let node = this.size() - 1
124+
while (node > this.top && this.greater(node, this.parent(node))) {
125+
this.swap(node, this.parent(node))
126+
node = this.parent(node)
127+
}
128+
}
129+
siftDown = () => {
130+
let node = this.top
131+
while (
132+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
133+
(this.right(node) < this.size() && this.greater(this.right(node), node))
134+
) {
135+
let maxChild =
136+
this.right(node) < this.size() &&
137+
this.greater(this.right(node), this.left(node))
138+
? this.right(node)
139+
: this.left(node)
140+
this.swap(node, maxChild)
141+
node = maxChild
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)