# 1244. Design A Leaderboard ###### tags: `Leetcode` `Medium` `Bloomberg` Link: https://leetcode.com/problems/design-a-leaderboard/ ## 思路 ### 思路一 用HashMap和Priority Queue **注意写法: 这里的priority queue里面的每个element都是Map.Entry** ### 思路二 用TreeMap存score和对应的人数,TreeMap可以对key排序 **注意写法: TreeMap 本来是increasing order的,但是通过```new TreeMap<>(Collections.reverseOrder());```可以让他变成decreasing order** ## Code ### 思路一 O(1) O(1) O(NlogK) ```python= class Leaderboard: def __init__(self): self.scores = collections.defaultdict(int) self.pq = [] def addScore(self, playerId: int, score: int) -> None: self.scores[playerId] += score def top(self, K: int) -> int: for score in self.scores.values(): heapq.heappush(self.pq, score) if len(self.pq)>K: heapq.heappop(self.pq) total = 0 for score in self.pq: total += score self.pq = [] return total def reset(self, playerId: int) -> None: del self.scores[playerId] ``` ```java= class Leaderboard { Map<Integer,Integer> scores; public Leaderboard() { scores = new HashMap<>(); } public void addScore(int playerId, int score) { scores.put(playerId, scores.getOrDefault(playerId, 0)+score); } public int top(int K) { Queue<Map.Entry<Integer,Integer>> q = new PriorityQueue<>((a,b)->(a.getValue()-b.getValue())); for(Map.Entry<Integer, Integer> entry: scores.entrySet()){ q.offer(entry); if(q.size()>K){ q.poll(); } } int total = 0; for(Map.Entry<Integer,Integer> entry:q){ total+=entry.getValue(); } return total; } public void reset(int playerId) { scores.remove(playerId); } } ``` ### 思路二 O(logN) O(logN) O(K) ```java= class Leaderboard { Map<Integer,Integer> scores; Map<Integer,Integer> sortedScores; public Leaderboard() { scores = new HashMap<>(); sortedScores = new TreeMap<>(Collections.reverseOrder()); } public void addScore(int playerId, int score) { if(!scores.containsKey(playerId)){ scores.put(playerId, score); sortedScores.put(score, sortedScores.getOrDefault(score, 0)+1); } else{ int preScore = scores.get(playerId); int preScoreCnt = sortedScores.get(preScore); if(preScoreCnt == 1) sortedScores.remove(preScore); else{ sortedScores.put(preScore, preScoreCnt-1); } sortedScores.put(preScore+score, sortedScores.getOrDefault(preScore+score, 0)+1); scores.put(playerId, preScore+score); } } public int top(int K) { int total = 0; int count = 0; for(Map.Entry<Integer, Integer> entry: sortedScores.entrySet()){ int times = entry.getValue(); int score = entry.getKey(); if(count+times < K){ count += times; total += times*score; } else{ total += (K-count)*score; count = K; break; } } return total; } public void reset(int playerId) { int preScore = scores.get(playerId); int preScoreCnt = sortedScores.get(preScore); if(preScoreCnt == 1) sortedScores.remove(preScore); else{ sortedScores.put(preScore, preScoreCnt-1); } scores.remove(playerId); } } ```