I have an assignment to solve this problem. There are a total of 12 test case files, 1 of which that I have failed due to exceeding limit on the script.
Question Description
Bob has somehow managed to obtain a class list of \$N\$ students that contains the name of the students, as well as their scores for an exam. The task is to generate the rank of each student in the class list.
Let \$S\$ be the number of students in the class list that have obtained a higher score than student \$X\$. The rank of student \$X\$ in the class list is formally defined as \$(S+1)\$. This means that if there are many students that obtain the same score, they will all have the same rank.
Input
The first line of input contains a single integer \$N\$, the number of students in the class list. \$N\$ lines will follow. Each line will describe one student in the following form: [name] [score].
Output
For each student, print the rank of the student in the following form: [name] [rank]. These students should be printed in the same order as the input.
Limits
\$1 \leq N \leq 50000
All the names of students will only contain uppercase and lowercase English letters with no spaces. The names will not be more than 20 characters long. It is possible that there can be 2 students with the same name.
All scores of students will range from 0 to 109 inclusive.
Does anyone have a solution to my problem? Do inform me if any more information is needed. Any other comments on coding styles and space complexities that may arise are also appreciated, though the focus should be the time.
Here's my code and test cases.
import java.util.*;
//Comparator to rank people by score in ascending order
//No tiebreaking for equal scores is considered in this question
class PairComparator implements Comparator<List<Object>> {
public int compare(List<Object> o1, List<Object> o2) {
return (Integer)o1.get(0) - (Integer)o2.get(0);
}
}
public class Ranking {
private void run() {
Scanner sc = new Scanner(System.in);
ArrayList<List<Object>> inputPairs = new ArrayList<>();
ArrayList<String> nameIterList = new ArrayList<>();//To store names in scanned order
HashMap<String, Integer> dupeCount = new HashMap<>();//To consider cases where there are people with same names
int count = sc.nextInt();
for (int i=0;i<count;i++) {
String name = sc.next();
int score = sc.nextInt();
name = checkDuplicates(nameIterList,name,dupeCount);//returns a unique name after considering duplicates
List<Object> pair = List.of(score,name);//simulates a struct data structure in C with non-homogeneous elements
inputPairs.add(pair);
nameIterList.add(name);
}
Collections.sort(inputPairs, (new PairComparator()).reversed());//descending order sorting
HashMap<String,Integer> nameRank = new HashMap<>();//name and respective rank in O(1) time
makeTable(nameRank,inputPairs);
for (String name: nameIterList) {
System.out.println(String.format("%s %d",name.trim(),nameRank.get(name)));
} //for displaying purposes, repeated name is printed
}
public static void main(String[] args) {
Ranking newRanking = new Ranking();
newRanking.run();
}
public static void makeTable(HashMap<String,Integer> nameRank, ArrayList<List<Object>> inputPairs) {
int lowestRank = 1;
int previousScore = (Integer)inputPairs.get(0).get(0);
for (int i=0;i<inputPairs.size();i++) {
List<Object> pairs = inputPairs.get(i);
String name = (String) pairs.get(1);
int score = (Integer) pairs.get(0);
int currentRank = i+1;//default rank if there are no tiebreakers
if (score==previousScore) {
currentRank = lowestRank;//takes the smallest possible rank for a tie-breaker
} else {
lowestRank = currentRank;//updates the smallest possible rank as tie-breaker is broken
previousScore = score;
}
nameRank.put(name,currentRank);//updates HashMap
}
}
public static String checkDuplicates(ArrayList<String> nameList, String name, HashMap<String,Integer> dupeCount) {
if (dupeCount.containsKey(name)) {
int count = dupeCount.get(name);
dupeCount.replace(name,count+1); //updates the duplicateTable
return name+ new String(new char[count]).replace('\0', ' ');//new name is appending with spaces, trimmed later on
} else {//entry not found, add in as the first one
dupeCount.put(name,1);
return name;//no change
}
}
}
Sample Inputs
25
Sloane 15
RartheCat 94
Taylor 34
Shark 52
Jayce 58
Westin 91
Blakely 6
Dexter 1
Davion 78
Saanvi 65
Tyson 15
Kiana 31
Roberto 88
Shark 55
MrPanda 25
Rar 26
Blair 12
RartheCat 81
Zip 74
Saul 58
ProfTan 77
SJShark 0
Georgia 79
Darian 44
Aleah 7
Sample Output
Sloane 19
RartheCat 1
Taylor 15
Shark 13
Jayce 10
Westin 2
Blakely 23
Dexter 24
Davion 6
Saanvi 9
Tyson 19
Kiana 16
Roberto 3
Shark 12
MrPanda 18
Rar 17
Blair 21
RartheCat 4
Zip 8
Saul 10
ProfTan 7
SJShark 25
Georgia 5
Darian 14
Aleah 22