Skip to content

Commit 40b4c96

Browse files
authored
Create 1244-design-a-leaderboard.js
1 parent fd833f6 commit 40b4c96

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

1244-design-a-leaderboard.js

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

0 commit comments

Comments
 (0)