Sort Students with a Comparator

Problem

Each input line has a name, an age and a score. Sort the students by score (highest first). If scores are equal, the younger student comes first. If age is also equal, sort by name in alphabetical order. Print the names, one per line.

Constraints

  • 1 <= lines <= 10^5

Examples

Input

amit 20 90
bela 19 90
chen 21 85

Output

bela
amit
chen

Solutions

Best approachTime O(n log n)Space O(n)

Sorting by several fields means comparing the first field, and only when it is equal comparing the next one. Compare numbers with Integer.compare, not by subtraction, because a - b can overflow for big values.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several lines.
 * Output  : The names in order.
 * Approach: Comparable or comparator.
 * Time    : O(n log n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: Student implements Comparable. compareTo defines the natural order: score high first, then age low first, then name.
        static class Student implements Comparable<Student> {
            final String name;
            final int age;
            final int score;

            Student(String name, int age, int score) {
                this.name = name;
                this.age = age;
                this.score = score;
            }

            @Override
            public int compareTo(Student other) {
                if (score != other.score) {
                    return Integer.compare(other.score, score);
                }
                if (age != other.age) {
                    return Integer.compare(age, other.age);
                }
                return name.compareTo(other.name);
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        // Step 2: Put the students in a list and sort it. Collections.sort uses compareTo.
        java.util.List<Student> students = new java.util.ArrayList<>();
        for (String line : lines) {
            String[] part = line.split(" ");
            students.add(new Student(part[0], Integer.parseInt(part[1]), Integer.parseInt(part[2])));
        }
        java.util.Collections.sort(students);

        // Step 3: Print the names in the new order.
        String[] output = new String[students.size()];
        for (int i = 0; i < output.length; i++) {
            output[i] = students.get(i).name;
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (1)
  1. What do you compare when the scores are equal?