要求
新一轮的「力扣杯」编程大赛即将启动,为了动态显示参赛者的得分数据,需要设计一个排行榜 Leaderboard。
请你帮忙来设计这个 Leaderboard 类,使得它有如下 3 个函数:
- addScore(playerId, score):
- 假如参赛者已经在排行榜上,就给他的当前得分增加 score 点分值并更新排行。
- 假如该参赛者不在排行榜上,就把他添加到榜单上,并且将分数设置为 score。
- top(K):返回前 K 名参赛者的 得分总和。
- reset(playerId):将指定参赛者的成绩清零(换句话说,将其从排行榜中删除)。题目保证在调用此函数前,该参赛者已有成绩,并且在榜单上。 请注意,在初始状态下,排行榜是空的。
示例 1:
输入:
["Leaderboard","addScore","addScore","addScore","addScore","addScore","top","reset","reset","addScore","top"]
[[],[1,73],[2,56],[3,39],[4,51],[5,4],[1],[1],[2],[2,51],[3]]
输出:
[null,null,null,null,null,null,73,null,null,null,141]
解释:
Leaderboard leaderboard = new Leaderboard ();
leaderboard.addScore(1,73); // leaderboard = [[1,73]];
leaderboard.addScore(2,56); // leaderboard = [[1,73],[2,56]];
leaderboard.addScore(3,39); // leaderboard = [[1,73],[2,56],[3,39]];
leaderboard.addScore(4,51); // leaderboard = [[1,73],[2,56],[3,39],[4,51]];
leaderboard.addScore(5,4); // leaderboard = [[1,73],[2,56],[3,39],[4,51],[5,4]];
leaderboard.top(1); // returns 73;
leaderboard.reset(1); // leaderboard = [[2,56],[3,39],[4,51],[5,4]];
leaderboard.reset(2); // leaderboard = [[3,39],[4,51],[5,4]];
leaderboard.addScore(2,51); // leaderboard = [[2,51],[3,39],[4,51],[5,4]];
leaderboard.top(3); // returns 141 = 51 + 51 + 39;
提示:
- 1 <= playerId, K <= 10000
- 题目保证 K 小于或等于当前参赛者的数量
- 1 <= score <= 100
- 最多进行 1000 次函数调用
核心代码
from collections import defaultdict
from heapq import *
class Leaderboard:
def __init__(self):
self.dic = defaultdict(int)
def addScore(self, playerId: int, score: int) -> None:
self.dic[playerId] += score
def top(self, K: int) -> int:
self.l = []
heapify(self.l)
for pid,score in self.dic.items():
if len(self.l) >= K:
if score > self.l[0]:
heappush(self.l,score)
heappop(self.l)
else:
heappush(self.l,score)
return sum(self.l)
def reset(self, playerId: int) -> None:
self.dic[playerId] = 0
# Your Leaderboard object will be instantiated and called as such:
# obj = Leaderboard()
# obj.addScore(playerId,score)
# param_2 = obj.top(K)
# obj.reset(playerId)
解题思路:TOP K 的问题就上堆,题目问前K个最大的,就是用最小堆。因为需要建立playerId 和 score 的映射,所以还要开个哈希表。然后每次调用 top()的时候,就遍历哈希表,建立并维护一个size 为 K 的最小堆即可。时间复杂度:O(NlogK),最坏情况下每个元素都要进堆。空间复杂度:O(N + K) = O(N),用了一个哈希表,一个最小堆。