Start learning free

LESSON 223 OF 671 · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

Top Scorer in Java: Find the Highest Value in a HashMap

Practice Read the full explanation

You get scores, a HashMap 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

    JAVA · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

    Top Scorer in Java, explained

    Problem overview

    The method topScorer receives scores, a HashMap<String, Integer> from players' names to their scores, and returns the name of the player with the highest score. If several players share the highest score, the answer is the name that comes first alphabetically.

    For {"Ana": 90, "Ben": 75, "Cara": 88} the answer is Ana. For {"Zoe": 82, "Ana": 82} both have 82, and Ana comes before Zoe, so the answer is Ana. A map with one player, {"Max": 0}, returns Max. The map always has at least one name, and every score is from 0 to 100.

    Approach

    Keep the best player seen so far and compare every entry with it. A map has no fixed order, so the code can't assume which entry comes first. That is why the tie rule has to be written into the comparison itself, rather than relying on the order of visiting.

    The starting values are an empty name and a score of -1. Every real score is at least 0, so the first player visited always beats -1 and replaces the starting values.

    Step by step

    1. Set bestName to an empty string and bestScore to -1.
    2. Loop over scores.entrySet(), with a Map.Entry<String, Integer> named entry.
    3. Read the key into name and the value into score, so the comparison below is easy to read.
    4. Check whether this player is better: a higher score, or an equal score and a name that comes first.
    5. If so, store the name and the score as the new best.
    6. After the loop, return bestName.

    The solution in Java

    class Solution {
        public String topScorer(HashMap<String, Integer> scores) {
            String bestName = "";
            int bestScore = -1;
            for (Map.Entry<String, Integer> entry : scores.entrySet()) {
                String name = entry.getKey();
                int score = entry.getValue();
                if (score > bestScore || (score == bestScore && name.compareTo(bestName) < 0)) {
                    bestName = name;
                    bestScore = score;
                }
            }
            return bestName;
        }
    }

    Two details are worth knowing:

    • name.compareTo(bestName) returns a negative number when name comes before bestName in alphabetical order, zero when they are equal and a positive number otherwise. The names here are a capital letter followed by lowercase letters, so plain alphabetical order is what compareTo gives.
    • The parentheses around the tie check matter. The tie only counts when the two scores are equal, so score == bestScore and the name test belong together. In Java && binds tighter than ||, and the brackets make that visible.

    It is worth tracing the second example. If Zoe is visited first, she becomes the best, with 82. When Ana arrives with the same score, the first part of the condition is false, but the second part is true, because "Ana".compareTo("Zoe") is negative. So Ana replaces her. If Ana is visited first, Zoe fails both parts and is skipped. Either order ends with Ana.

    Edge cases and common mistakes

    • Forgetting the tie rule. If the condition is only score > bestScore, the first entry with the top score wins, and for {"Zoe": 82, "Ana": 82} that depends on the map's internal order. The code might return either name.
    • Starting bestScore at 0. A player with 0 points, like Max in the last example, would never beat it, and the method would return an empty string. Starting at -1 avoids that.
    • Comparing names with ==. Strings are objects, so == compares references. Use equals for equality and compareTo for order.
    • Returning the score instead of the name. The method returns a String.

    Testing

    Running the solution on the three examples gives:

    Ana
    Ana
    Max
    Keep going with Java500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free