题目描述:
新一轮的「力扣杯」编程大赛即将启动,为了动态显示参赛者的得分数据,需要设计一个排行榜 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 次函数调用
方法1:
主要思路:解题链接汇总
(1)使用数组 vector counts 统计各个账户的分数,使用map<int,int,greater>mp以分数作为键,进行降序排序,统计各个分数的人数;
(2)调用addScore和reset时,注意更新分数的同时,更新对应分数的数量变更;
(3)调用top时,按序遍历,找到前k个人的分数和即可;
class Leaderboard {
public:
vector<int> counts;
map<int,int,greater<int>> mp;
Leaderboard() {
counts=vector<int>(100001,0);
}
void addScore(int playerId, int score) {
if(counts[playerId]!=0){//更新分数对应的人数
--mp[counts[playerId]];
}
//更新分数和对应的人数
counts[playerId]+=score;
++mp[counts[playerId]];
}
int top(int K) {
int res=0;
for(auto& it:mp){
if(it.second<=K){
res+=it.first*it.second;//加上当前分数下,所有人的分数
K-=it.second;
}
else{
res+=it.first*K;
K=0;
}
if(K==0){//找到了K个人
break;
}
}
return res;
}
void reset(int playerId) {
//更新分数和对应的人数
--mp[counts[playerId]];
counts[playerId]=0;
}
};
/**
* Your Leaderboard object will be instantiated and called as such:
* Leaderboard* obj = new Leaderboard();
* obj->addScore(playerId,score);
* int param_2 = obj->top(K);
* obj->reset(playerId);
*/