Skip to content

Commit 0b760be

Browse files
authored
Create 2102-sequentially-ordinal-rank-tracker.js
1 parent e75e86a commit 0b760be

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const maxComp = (a, b) => {
2+
return a[1] === b[1] ? b[0].localeCompare(a[0]) > 0 : a[1] > b[1]
3+
}
4+
5+
const minComp = (a, b) => {
6+
return a[1] === b[1] ? a[0].localeCompare(b[0]) > 0: a[1] < b[1]
7+
}
8+
9+
const SORTracker = function() {
10+
// max
11+
this.pq = new PriorityQueue(maxComp)
12+
// min
13+
this.best = new PriorityQueue(minComp)
14+
};
15+
16+
/**
17+
* @param {string} name
18+
* @param {number} score
19+
* @return {void}
20+
*/
21+
SORTracker.prototype.add = function(name, score) {
22+
this.pq.push([name, score])
23+
while(!this.best.isEmpty() && maxComp(this.pq.peek(), this.best.peek())) {
24+
const a = this.best.pop(), b = this.pq.pop()
25+
this.best.push(b)
26+
this.pq.push(a)
27+
}
28+
};
29+
30+
/**
31+
* @return {string}
32+
*/
33+
SORTracker.prototype.get = function() {
34+
const tmp = this.pq.pop()
35+
this.best.push(tmp)
36+
return tmp[0]
37+
};
38+
39+
/**
40+
* Your SORTracker object will be instantiated and called as such:
41+
* var obj = new SORTracker()
42+
* obj.add(name,score)
43+
* var param_2 = obj.get()
44+
*/
45+
46+
class PriorityQueue {
47+
constructor(comparator = (a, b) => a > b) {
48+
this.heap = []
49+
this.top = 0
50+
this.comparator = comparator
51+
}
52+
size() {
53+
return this.heap.length
54+
}
55+
isEmpty() {
56+
return this.size() === 0
57+
}
58+
peek() {
59+
return this.heap[this.top]
60+
}
61+
push(...values) {
62+
values.forEach((value) => {
63+
this.heap.push(value)
64+
this.siftUp()
65+
})
66+
return this.size()
67+
}
68+
pop() {
69+
const poppedValue = this.peek()
70+
const bottom = this.size() - 1
71+
if (bottom > this.top) {
72+
this.swap(this.top, bottom)
73+
}
74+
this.heap.pop()
75+
this.siftDown()
76+
return poppedValue
77+
}
78+
replace(value) {
79+
const replacedValue = this.peek()
80+
this.heap[this.top] = value
81+
this.siftDown()
82+
return replacedValue
83+
}
84+
85+
parent = (i) => ((i + 1) >>> 1) - 1
86+
left = (i) => (i << 1) + 1
87+
right = (i) => (i + 1) << 1
88+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
89+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
90+
siftUp = () => {
91+
let node = this.size() - 1
92+
while (node > this.top && this.greater(node, this.parent(node))) {
93+
this.swap(node, this.parent(node))
94+
node = this.parent(node)
95+
}
96+
}
97+
siftDown = () => {
98+
let node = this.top
99+
while (
100+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
101+
(this.right(node) < this.size() && this.greater(this.right(node), node))
102+
) {
103+
let maxChild =
104+
this.right(node) < this.size() &&
105+
this.greater(this.right(node), this.left(node))
106+
? this.right(node)
107+
: this.left(node)
108+
this.swap(node, maxChild)
109+
node = maxChild
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)