[LeetCode] 1244. Design A Leaderboard

Design a Leaderboard class, which has 3 functions:

addScore(playerId, score): Update the leaderboard by adding score to the given player's score. If there is no player with such id in the leaderboard, add him to the leaderboard with the given score.

top(K): Return the score sum of the top K players.

reset(playerId): Reset the score of the player with the given id to 0 (in other words erase it from the leaderboard). It is guaranteed that the player was added to the leaderboard before calling this function.

Initially, the leaderboard is empty.

Example 1:
Input:
["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]]
Output:
[null,null,null,null,null,null,73,null,null,null,141]
Explanation:
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;
Constraints:
1 <= playerId, K <= 10000
It's guaranteed that K is less than or equal to the current number of players.
1 <= score <= 100
There will be at most 1000 function calls.

力扣排行榜。

新一轮的「力扣杯」编程大赛即将启动,为了动态显示参赛者的得分数据,需要设计一个排行榜 Leaderboard。
请你帮忙来设计这个 Leaderboard 类,使得它有如下 3 个函数:
addScore(playerId, score):假如参赛者已经在排行榜上,就给他的当前得分增加 score 点分值并更新排行。
假如该参赛者不在排行榜上,就把他添加到榜单上,并且将分数设置为 score。
top(K):返回前 K 名参赛者的 得分总和。
reset(playerId):将指定参赛者的成绩清零(换句话说,将其从排行榜中删除)。题目保证在调用此函数前,该参赛者已有成绩,并且在榜单上。
请注意,在初始状态下,排行榜是空的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-a-leaderboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路一

这是一道设计题。我的思路如下,我们需要一个 hashmap,一个 treemap。除了题目要求实现的函数之外,我还需要一个 helper 函数。他的作用是当某一个 player 的分数有变动的时候,我需要将对应 unique score 记录的 player 的个数做出修改。其余部分参见代码。
hashmap - <playerId, his score>
treemap - <each unique score, how many people have this same score>

复杂度

时间O(n)
空间O(n)

代码

Java实现

class Leaderboard {
	// <playerId, score>
	HashMap<Integer, Integer> map;
	// <score, num of people>
	TreeMap<Integer, Integer> treemap;
 
	public Leaderboard() {
		map = new HashMap<>();
		treemap = new TreeMap<>();
	}
 
	public void addScore(int playerId, int score) {
		Integer curScore = map.get(playerId);
		if (curScore != null) {
			helper(curScore);
			curScore += score;
			map.put(playerId, curScore);
			if (treemap.containsKey(curScore)) {
				treemap.put(curScore, treemap.get(curScore) + 1);
			} else {
				treemap.put(curScore, 1);
			}
		} else {
			map.put(playerId, score);
			treemap.put(score, treemap.getOrDefault(score, 0) + 1);
		}
	}
 
	public int top(int K) {
		int sum = 0;
		Map.Entry<Integer, Integer> scoreEntry = treemap.lastEntry();
		while (K > 0 && scoreEntry != null) {
			int count = Math.min(scoreEntry.getValue(), K);
			sum += scoreEntry.getKey() * count;
			scoreEntry = treemap.lowerEntry(scoreEntry.getKey());
			K -= count;
		}
		return sum;
	}
 
	public void reset(int playerId) {
		int score = map.get(playerId);
		map.put(playerId, 0);
		helper(score);
		treemap.put(0, treemap.getOrDefault(0, 0) + 1);
	}
 
	private void helper(int score) {
		int count = treemap.get(score);
		if (count <= 1) {
			treemap.remove(score);
		} else {
			treemap.put(score, count - 1);
		}
	}
}
 
/**
 * 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);
 */

思路二

二刷我再提供另外一种思路,需要用到 hashmap 和一个 list。同时这里我需要自己创建一个 node class,存放每个元素的 id 和 score。hashmap 存的是<id, Node>,list 存的是所有的 node。

  • addScore, 如果某个 id 不存在,则创建一个新的 node,记录其 score,并分别放入 hashmap 和 list。如果某个 id 存在,则去 hashmap 中找到这个 node,累加他的 score
  • top,对 list 按 score 从大到小排序,然后取前 k 个元素,累加他们的 score
  • reset,按 playerId 去 hashmap 中找到这个对应的 node,将其 score 置为 0

复杂度

时间O(nlogn) - sort
空间O(n)

代码

Java实现

class Leaderboard {
	class Node {
		int id;
		int score;
 
		public Node(int id, int score) {
			this.id = id;
			this.score = score;
		}
	}
	HashMap<Integer, Node> map;
	List<Node> list;
 
	public Leaderboard() {
		map = new HashMap<>();
		list = new ArrayList<>();
	}
 
	public void addScore(int playerId, int score) {
		if (map.containsKey(playerId)) {
			map.get(playerId).score += score;
		} else {
			Node node = new Node(playerId, score);
			map.put(playerId, node);
			list.add(node);
		}
	}
 
	public int top(int K) {
		Collections.sort(list, (a, b) -> b.score - a.score);
		int sum = 0;
		for (int i = 0; i < Math.min(K, list.size()); i++) {
			sum += list.get(i).score;
		}
		return sum;
	}
 
	public void reset(int playerId) {
		map.get(playerId).score = 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);
 */
posted @ 2021-04-27 06:32  CNoodle  阅读(648)  评论(0编辑  收藏  举报