MediumPythonJavaScriptTypeScript
System Design — Game Leaderboard
System DesignSortingHash Map
Scores go up and down, and the product needs "top K" and "my rank" at any time.
solve(args, ops) builds new Leaderboard() and replays ops:
add(player, delta)— adddelta(may be negative) to the player's score; an unknown
player starts at 0. Returns the player's new score.
top(k)— return the ids of thekbest players, best first. Fewer players thankis fine.rank(player)— the 1-based position of the player, or-1for an unknown player.reset(player)— remove the player from the board. Returns nothing.
Ordering is pinned: higher score first; on equal scores the smaller player id (plain
string comparison) comes first. Players with equal scores therefore do *not* share a rank.
A sort on every query is acceptable here. In production you would keep a sorted structure
(balanced tree, skip list or Redis sorted set) so top and rank are O(log n) — be ready to
say so.
Example
add("a",10) add("b",20) add("c",20) top(2) → ["b","c"] rank("a") → 3Sample tests
Test #1Ties broken by id, resets and re-ranking
Input: [[],[["add","a",10],["add","b",20],["add","c",20],["top",2],["rank","a"],["add","a",15],["top",1],["rank","b"],["reset","a"],["rank","a"],["top",5]]]
Output: [10,20,20,["b","c"],3,25,["a"],2,null,-1,["b","c"]]
Test #2Empty leaderboard
Input: [[],[["top",3],["rank","ghost"]]]
Output: [[],-1]
Test #3Negative scores
Input: [[],[["add","x",5],["add","x",-8],["add","y",-1],["top",2],["rank","x"]]]
Output: [5,-3,-1,["y","x"],2]