---
# System prepended metadata

title: 1244. Design A Leaderboard
tags: [Leetcode, Bloomberg, Medium]

---

# 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);
    }
}
```