Start learning free

LESSON 226 OF 674 · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

Top Scorer in C#: Tracking the Best Entry in a Dictionary

Practice Read the full explanation

You get scores, a Dictionary from players' names to their scores. Return the name of the player with the highest score.

Several players may share the highest score. Then return the name that comes first in alphabetical order.

 

Example 1:

Input: scores = {"Ana": 90, "Ben": 75, "Cara": 88}
Output: "Ana"
Explanation: 90 is the highest score, and it is Ana's.

Example 2:

Input: scores = {"Zoe": 82, "Ana": 82}
Output: "Ana"
Explanation: Both have 82. "Ana" comes before "Zoe" in alphabetical order.

Example 3:

Input: scores = {"Max": 0}
Output: "Max"
Explanation: Max is the only player, so his score is the highest.

 

Constraints:

  • scores has at least one name.
  • Every score is a whole number from 0 to 100.
  • Each name is a capital letter followed by lowercase letters, like "Ana".
STEP 1 OF 6
    Ctrl + Enter to check

    C# · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

    Top Scorer in C#, explained

    Problem overview

    The method TopScorer receives scores, a Dictionary<string, int> from player names to scores. It returns the name of the player with the highest score. When several players share the top score, it returns the name that comes first alphabetically.

    For {"Ana": 90, "Ben": 75, "Cara": 88} the answer is Ana, because 90 is the highest score. For {"Zoe": 82, "Ana": 82} both players have 82, so the alphabetical rule picks Ana. A dictionary with only {"Max": 0} returns Max.

    Approach

    Walk through the entries once and remember the best player seen so far: a name and a score. For each entry, ask whether this player beats the best one. If so, replace the best.

    A player beats the best when the score is higher, or when the score is equal and the name comes first alphabetically. A dictionary promises no order, so the tie rule has to be in the comparison itself. Otherwise the answer would depend on which name the loop happened to meet first.

    The starting values need care. All scores are at least 0, so a starting score of -1 is beaten by the very first player. The starting name is an empty string.

    Step by step

    1. Set up the best so far: bestName as an empty string and bestScore as -1.
    2. Loop over the entries with foreach (var pair in scores).
    3. Read the key and value into name and score, so the comparison is easy to read.
    4. Test whether this player wins: a higher score, or an equal score and a name that sorts earlier. name.CompareTo(bestName) < 0 is true when name comes before bestName.
    5. Update both variables inside the if.
    6. Return bestName after the loop.

    The solution in C#

    class Solution {
        public string TopScorer(Dictionary<string, int> scores) {
            string bestName = "";
            int bestScore = -1;
            foreach (var pair in scores) {
                string name = pair.Key;
                int score = pair.Value;
                if (score > bestScore || (score == bestScore && name.CompareTo(bestName) < 0)) {
                    bestName = name;
                    bestScore = score;
                }
            }
            return bestName;
        }
    }
    

    Run on the three examples, it returns:

    Ana
    Ana
    Max
    

    The details worth knowing:

    • var pair is a KeyValuePair<string, int>; Key and Value are its properties.
    • CompareTo returns a negative number, zero or a positive number, so test it against 0 rather than against -1.
    • The parentheses around the tie check matter: && binds tighter than || in C#, but the parentheses make the intent clear to the reader.

    Why the tie rule works

    Think of the loop as keeping one champion. Each new entry challenges the champion, and the challenger wins only if the score is strictly higher, or the score is equal and the name sorts earlier. Both conditions are decided by the two entries alone, never by their position in the dictionary. That is why any visiting order ends with the same champion: the "best" entry is the maximum under a fixed ranking (score first, then name), and a maximum does not depend on the order you scan in.

    For {"Zoe": 82, "Ana": 82} there are two possible visiting orders. If Zoe comes first, she becomes the champion with 82, then Ana challenges with an equal score and a name that sorts earlier, so she takes over. If Ana comes first, Zoe's challenge fails the name test. Both orders return Ana.

    Edge cases and common mistakes

    • Ties. With {"Ana": 82, "Zoe": 82} and {"Zoe": 82, "Ana": 82} the answer is Ana both times, because the rule never looks at the order of the entries.
    • A top score of 0. With {"Max": 0}, a starting bestScore of 0 would never be beaten, and an empty name never sorts after "Max", so the method would return an empty string. Starting at -1 avoids this.
    • Returning the score. The method returns the name, a string, not the number.
    • Indexing the dictionary by position. scores[0] is a lookup of the key 0, not the first entry, and it doesn't compile for string keys.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free