
Problem Statement
In this task, we are given a list called items
, where each element of the list is a pair [IDi, scorei]
. This pair represents a score (scorei
) obtained by a student identified by IDi
. Our goal is to compute the average of the top five scores for each student and then return this information in a sorted format based on their IDs.
The specific steps to accomplish are:
- For each student, identified by their unique ID, gather all the scores they have obtained.
- From the collected scores for each student, determine the top five scores.
- Calculate the average of these top five scores using integer division (where any fractional part is discarded).
- Return the result as a list of pairs, where each pair consists of
[IDj, topFiveAveragej]
. This list should be sorted byIDj
in ascending order.
Examples
Example 1
Input:
items = [[1,91],[1,92],[2,93],[2,97],[1,60],[2,77],[1,65],[1,87],[1,100],[2,100],[2,76]]
Output:
[[1,87],[2,88]]
Explanation:
Student 1: Scores = [91, 92, 60, 65, 87, 100] Top 5 = [100, 92, 91, 87, 65] → Avg = (100 + 92 + 91 + 87 + 65) // 5 = 87 Student 2: Scores = [93, 97, 77, 100, 76] Top 5 = [100, 97, 93, 77, 76] → Avg = (100 + 97 + 93 + 77 + 76) // 5 = 88
Example 2
Input:
items = [[1,100],[7,100],[1,100],[7,100],[1,100],[7,100],[1,100],[7,100],[1,100],[7,100]]
Output:
[[1,100],[7,100]]
Explanation:
Both students have exactly five scores of 100. Their average is 100.
Constraints
1 <= items.length <= 1000
items[i].length == 2
1 <= IDi <= 1000
0 <= scorei <= 100
- For each
IDi
, there will be at least five scores.
Approach and Intuition
To solve this efficiently:
Group scores by student ID using a dictionary where the key is the student ID and the value is a list of their scores.
Process each student:
- Sort their scores in descending order.
- Take the top five scores and compute the average using integer division.
Construct the result list as
[ID, average]
and sort it by student ID in ascending order.
This ensures we accurately and efficiently compute the required averages under the given constraints.
Solutions
- C++
- Java
class Solution {
private:
int numBestScores;
public:
vector<vector<int>> calculateHighFive(vector<vector<int>>& records) {
this->numBestScores = 5;
map<int, priority_queue<int, vector<int>, greater<int>>> studentScores;
for (const auto &record: records) {
int studentId = record[0];
int score = record[1];
studentScores[studentId].push(score);
if (studentScores[studentId].size() > this->numBestScores)
studentScores[studentId].pop();
}
vector<vector<int>> result;
for (auto &[id, scores]: studentScores) {
int sum = 0;
for (int i = 0; i < this->numBestScores; ++i) {
sum += scores.top();
scores.pop();
}
result.push_back({id, sum / this->numBestScores});
}
return result;
}
};
The "High Five" problem in C++ involves calculating the average of the top five scores for each student from a list of student-score records. The provided C++ code defines a class Solution
with a method calculateHighFive
to solve this task.
Here's a brief solution summary:
- Use a
map
where each key is a student ID and each value is a priority queue (min-heap) to store the scores of the respective student. - Iterate over each record in the input list:
- For each student, push the score into the student's priority queue.
- Ensure that the priority queue never holds more than five scores by popping the smallest score if the queue size exceeds five (retaining only the top scores).
- After processing all records, iterate over the map to calculate the average of the top five scores:
- Sum the scores retrieved from the top of the priority queue.
- Compute the average and store the result as
studentId
and respective average score.
- Return a list of these averages for all students.
This approach efficiently calculates and maintains only the necessary scores (top five) for each student using priority queues, ensuring optimal use of memory and processing time.
class Solution {
private int numScores = 5;
public int[][] topFive(int[][] results) {
TreeMap<Integer, PriorityQueue<Integer>> scoreMap = new TreeMap<>();
for (int[] result : results) {
int studentId = result[0];
int score = result[1];
if (!scoreMap.containsKey(studentId))
scoreMap.put(studentId, new PriorityQueue<>());
scoreMap.get(studentId).add(score);
if (scoreMap.get(studentId).size() > numScores)
scoreMap.get(studentId).poll();
}
List<int[]> res = new ArrayList<>();
for (int id : scoreMap.keySet()) {
int total = 0;
for (int i = 0; i < numScores; ++i)
total += scoreMap.get(id).poll();
res.add(new int[] {id, total / numScores});
}
int[][] resultArray = new int[res.size()][];
return res.toArray(resultArray);
}
}
This Java solution for the "High Five" problem calculates the average of the top five scores for each student using a TreeMap<Integer, PriorityQueue<Integer>>
.
- Initialize a
TreeMap
calledscoreMap
where the key is the student ID and the value is aPriorityQueue
to store the scores. - Iterate through the input array
results
. For each score:- Check if the student ID exists in
scoreMap
. - If not, add the student ID and a new PriorityQueue to
scoreMap
. - Insert the score into the PriorityQueue. If the size of the PriorityQueue exceeds five, remove the lowest score to ensure only the top five scores are retained.
- Check if the student ID exists in
- After processing all scores, initialize a
List<int[]>
to store the results. - Iterate through the entries in
scoreMap
, computing the average of the scores in each PriorityQueue.- Poll each score from the PriorityQueue and compute the sum.
- Calculate the average and add it to the results list.
- Convert the list to an array and return.
This approach ensures the solution dynamically manages a list of top scores for each student efficiently, maintaining a constant size for the PriorityQueue. It handles varying number of scores and students seamlessly.
No comments yet.