1. Using Sorting

class Solution {

    private int K;

    public int[][] highFive(int[][] items) {
        this.K = 5;

        Arrays.sort(
                items,
                new Comparator<int[]>() {
                    @Override
                    public int compare(int[] a, int[] b) {
                        if (a[0] != b[0])
                            // item with lower id goes first
                            return a[0] - b[0];
                        // in case of tie for ids, item with higher score goes first
                        return b[1] - a[1];
                    }
                });

        List<int[]> solution = new ArrayList<>();
        int n = items.length;
        int i = 0;
        while (i < n) {
            int id = items[i][0];
            int sum = 0;
            // obtain total using the top 5 scores
            for (int k = i; k < i + this.K; ++k)
                sum += items[k][1];
            // ignore all the other scores for the same id
            while (i < n && items[i][0] == id)
                i++;
            solution.add(new int[] {id, sum / this.K});
        }

        int[][] solutionArray = new int[solution.size()][];
        return solution.toArray(solutionArray);
    }
}

Time & Space Complexity

  • Time complexity: O(NlogN)O(N \log N)
  • Space complexity: O(N)O(N)

Where NN is the total number of items.


2. Using Map and Max Heap

class Solution {
    private int K;

    public int[][] highFive(int[][] items) {
        this.K = 5;
        TreeMap<Integer, Queue<Integer>> allScores = new TreeMap<>();
        for (int[] item : items) {
            int id = item[0];
            int score = item[1];
            if (!allScores.containsKey(id))
                // max heap
                allScores.put(id, new PriorityQueue<>((a,b) -> b - a));
            // Add score to the max heap
            allScores.get(id).add(score);
        }

        List<int[]> solution = new ArrayList<>();

        for (int id : allScores.keySet()) {
            int sum = 0;
            // obtain the top k scores (k = 5)
            for (int i = 0; i < this.K; ++i)
                sum += allScores.get(id).poll();
            solution.add(new int[] {id, sum / this.K});
        }
        int[][] solutionArray = new int[solution.size()][];
        return solution.toArray(solutionArray);
    }
}

Time & Space Complexity

  • Time complexity: O(NlogN)O(N \log N)
  • Space complexity: O(N)O(N)

Where NN is the total number of items.


3. Using Map and Min Heap

class Solution:
    def highFive(self, items: List[List[int]]) -> List[List[int]]:
        K = 5
        all_scores = defaultdict(list)  # Using defaultdict with list for min heap
        
        for item in items:
            student_id = item[0]
            score = item[1]
            
            heapq.heappush(all_scores[student_id], score)
            
            if len(all_scores[student_id]) > K:
                heapq.heappop(all_scores[student_id])
        
        solution = []
        for student_id in sorted(all_scores.keys()):
            total = sum(all_scores[student_id])
            solution.append([student_id, total // K])
        
        return solution

Time & Space Complexity

  • Time complexity: O(NlogN)O(N \log N)
  • Space complexity: O(N)O(N)

Where NN is the total number of items.