Start learning free

LESSON 265 OF 671 · RECORDS, SORTING & BUILT-INS

Leaderboard in Java: Sorting Records by Score

Practice Read the full explanation

You get an ArrayList of players, players. Each player is a pair: a name and a score, like ("Ava", 30).

Return the names, from the highest score to the lowest.

Players with the same score go in alphabetical order of their names.

The starter code shows how your language holds a pair.

 

Example 1:

Input: players = [("Ava", 30), ("Ben", 25), ("Cy", 40)]
Output: ["Cy", "Ava", "Ben"]
Explanation: Cy has the most points, 40.
Then come Ava with 30 and Ben with 25.

Example 2:

Input: players = [("Mia", 50), ("Leo", 70), ("Ava", 50)]
Output: ["Leo", "Ava", "Mia"]
Explanation: Leo leads with 70.
Ava and Mia both have 50.
Ava comes first from A to Z.

Example 3:

Input: players = [("Zoe", 0)]
Output: ["Zoe"]
Explanation: Zoe is the only player.

 

Constraints:

  • players has 1 to 100 players.
  • Every score is a whole number from 0 to 1000.
  • Each name is a capital letter followed by lowercase letters, like "Ava".
  • No two players have the same name.
STEP 1 OF 6
    Ctrl + Enter to check

    JAVA · RECORDS, SORTING & BUILT-INS

    Leaderboard in Java, explained

    Problem overview

    The method leaderboard gets a list of Player records, each with a name and a score. It returns only the names, from the highest score to the lowest. Players with equal scores are ordered alphabetically by name. The lesson provides the record: record Player(String name, int score) {}.

    For Ava 30, Ben 25, Cy 40 the result is [Cy, Ava, Ben]. For Mia 50, Leo 70, Ava 50 it is [Leo, Ava, Mia]: Leo leads with 70, and Ava comes before Mia among the two 50s. A single player, Zoe 0, gives [Zoe].

    Approach

    The job has two parts. First sort the players with a comparator that has two rules, higher score first and then name from A to Z. Then copy the names, in the new order, into a fresh list. Sorting the records and keeping the scores until the end means the names never lose their scores along the way.

    Step by step

    1. Call players.sort with a lambda (a, b) -> { ... } that has a body in braces. First rule: if a.score() != b.score(), return b.score() - a.score(). The subtraction is written the other way round from an ascending sort. When a has more points, the result is negative, so a goes first.
    2. Second rule, for equal scores: return a.name().compareTo(b.name()), which is alphabetical order.
    3. After the sort, create an empty List<String> named names as a new ArrayList.
    4. Loop over the players with for (Player player : players). They are already in the right order.
    5. Inside the loop, add player.name() to names. Only the names go in, not the scores.
    6. Return names after the loop.

    The solution in Java

    class Solution {
        public List<String> leaderboard(List<Player> players) {
            players.sort((a, b) -> {
                if (a.score() != b.score()) {
                    return b.score() - a.score();
                }
                return a.name().compareTo(b.name());
            });
            List<String> names = new ArrayList<>();
            for (Player player : players) {
                names.add(player.name());
            }
            return names;
        }
    }
    

    Scores are between 0 and 1000, so subtracting them can't overflow. The first example prints as [Cy, Ava, Ben], the second as [Leo, Ava, Mia] and the third as [Zoe].

    Edge cases and common mistakes

    • Wrong direction. a.score() - b.score() sorts from the lowest score up. The higher score must make the result negative for a, so the order is b minus a.
    • Missing tie rule. Without the name comparison, equal scores keep their input order, so Mia 50, Leo 70, Ava 50 would give [Leo, Mia, Ava].
    • Comparing names in the wrong direction. The names use a.name().compareTo(b.name()), ascending, even though the scores are descending. The two rules go in different directions.
    • Sorting a list that can't change. sort reorders the list in place, so a list that can't be modified, such as one made with List.of(...), throws UnsupportedOperationException.
    • Returning records. The method returns a list of names. Returning players would hand back whole records.

    Complexity

    Sorting takes O(n log n) comparisons for n players, and the copy loop is O(n), so the sort dominates. The new list of names uses O(n) extra space.

    Testing

    Try the lesson's examples and a few of your own:

    • Ava 30, Ben 25, Cy 40 gives [Cy, Ava, Ben].
    • Mia 50, Leo 70, Ava 50 gives [Leo, Ava, Mia].
    • Zoe 0 gives [Zoe].

    Names are unique, so two players never tie on both rules, and the order of the result is fully decided. Also try a list where every player has the same score. The first rule never applies, and the result is simply the names from A to Z.

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