Problem overview
The method topScorer receives scores, a dictionary from player names to whole-number scores between 0 and 100. It returns the name with the highest score. When several players share the top score, it returns the name that comes first alphabetically. The dictionary always has at least one player.
For {"Ana": 90, "Ben": 75, "Cara": 88} the answer is "Ana". For {"Zoe": 82, "Ana": 82} both players have 82, and "Ana" comes before "Zoe". For {"Max": 0} the only player wins with a score of 0.
Approach
Keep the best player seen so far, and let each entry challenge it. A challenger wins if its score is higher, or if the scores are equal and its name sorts earlier. After every entry has been compared, the one left standing is the answer.
This never depends on the order in which the loop visits the dictionary. A tie is settled by the names, not by who came first, so any visiting order gives the same result.
Why a loop over items()
The loop needs both halves of every entry: the name to return, and the score to compare. scores.items() gives both at once, as pairs, and Python unpacks each pair into name and score. Looping over the dictionary alone would give only names, and every score would need a second lookup with scores[name].
Step by step
- Start with
bestName = ""andbestScore = -1. Scores are never below 0, so the first player always beats -1 and takes over. - Loop with
for name, score in scores.items()to get each key with its value. - Write the challenge test:
score > bestScore, or the scores are equal andname < bestName. - When the test is true, store the challenger's name and score as the new best.
- After the loop, return
bestName.
The solution in Python
class Solution:
def topScorer(self, scores: Dict[str, int]) -> str:
bestName = ""
bestScore = -1
for name, score in scores.items():
if score > bestScore or (score == bestScore and name < bestName):
bestName = name
bestScore = score
return bestName
Two details are worth knowing:
<on two strings compares them alphabetically (by character codes, letter by letter). Here every name is a capital letter followed by lowercase letters, so this matches the alphabetical order the task asks for.- In Python
andbinds tighter thanor, so the parentheses do not change the result. They show the reader that the name comparison belongs with the equal-scores check, and it is the form the lesson uses.
Testing
These results come from running the solution:
| scores | result |
|---|---|
{"Ana": 90, "Ben": 75, "Cara": 88} | Ana |
{"Zoe": 82, "Ana": 82} | Ana |
{"Max": 0} | Max |
{"Zoe": 82, "Ana": 82, "Bo": 1} | Ana |
Edge cases and common mistakes
- Starting
bestScoreat 0. A lone player with score 0 would never beat it, and the method would return the empty string. Starting at -1 avoids that. - Using
>=alone. It picks whoever is visited last among equal scores, which depends on the dictionary's order, not on the alphabet. - Returning the score. The method returns the name, not the number.
- Checking the name without checking the score.
name < bestNameon its own would pick the alphabetically first player no matter how low the score is.
