Leetcode 1086. High Five Java 解法

博客围绕计算学生成绩平均分展开,介绍了两种方法。方法一是暴力排序法,作者用此方法未通过部分测试用例,思路是按成绩排序,用集合去重并构造结果。方法二使用HashMap和PriorityQueue,还介绍了PriorityQueue的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先吐槽一下这个难度,咋也不能是easy啊,和其他easy的不在一个量级。

Given a list of scores of different students, return the average score of each student's top five scores in the order of each student's id.

Each entry items[i] has items[i][0] the student's id, and items[i][1] the student's score.  The average score is calculated using integer division.

 

Example 1:

Input: [[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: 
The average of the student with id = 1 is 87.
The average of the student with id = 2 is 88.6. But with integer division their average converts to 88.

 

Note:

  1. 1 <= items.length <= 1000
  2. items[i].length == 2
  3. The IDs of the students is between 1 to 1000
  4. The score of the students is between 1 to 100
  5. For each student, there are at least 5 scores

Approach #1 Brute Force, sorting

这是我的解法,还有一些莫名其妙的test case没有通过。

class Solution {
    public int[][] highFive(int[][] items) {
        int rows = items.length;
        Set<Integer> set = new HashSet();

        // first sort all items by grades
        for(int i=0; i<rows; i++){
            int min = i;
            set.add(items[i][0]);

            for(int j=i+1; j<rows;j++){
                if(items[j][1]<items[min][1]){
                    min = j;
                }
            }
            if(min!=i){
                int[] temp = items[i];
                items[i] = items[min];
                items[min] = temp;
            }
        }
        
        // now start construct the answer array
        Object[] obj = set.toArray(); 
		int id[] = new int[obj.length];
        int[][] ans = new int[obj.length][2];
        
		for (int i = 0; i <obj.length; i++) {
			id[i] = (int) obj[i];
            ans[i][0] = id[i];
        }
        
        // now focus on calculating the average score
        for (int i=0; i<obj.length; i++){
            int count = 0;
            int sum = 0;
            int j = rows-1;
            while(count<5){       
                if(items[j][0] == ans[i][0]){
                    sum += items[j][1];
                    count += 1;
                    j-=1;
                }
               
                else {j-=1; continue;}
            }
            ans[i][1] = sum/5;
        }
        return ans;
    }
}

结果:

莫名其妙少了一个学生的成绩。

Wrong Answer

Input

[[1,46],[1,44],[1,92],[1,26],[1,90],[2,7],[2,76],[2,20],[2,46],[2,68],[3,8],[3,55],[3,66],[3,55],[3,62],[4,22],[4,90],[4,92],[4,13],[4,89],[5,13],[5,20],[5,82],[5,83],[5,25],[6,83],[6,89],[6,33],[6,16],[6,70],[7,85],[7,15],[7,33],[7,72],[7,9]]

Output

[[1,59],[2,43],[3,49],[4,61],[5,44],[6,58]]

Expected

[[1,59],[2,43],[3,49],[4,61],[5,44],[6,58],[7,42]]

分析

我的思路是,先把所有的行按照学生成绩这一列来排序,然后用set储存所有学生的id来避免重复,再用set构造最终解的第一列,然后从排好序的成绩列表里,按照id,每次选最高的5个算出均分。

 

Approach #2 HashMap, PriorityQueue

摸一下大神的解法。


class Solution {
    public int[][] highFive(int[][] items) {
    
        HashMap<Integer, PriorityQueue<Integer>> map = new HashMap<>();
        
       for(int[] item : items){
           int id = item[0];
           int score = item[1];
           
           if(!map.containsKey(id)){
               PriorityQueue<Integer> pq = new PriorityQueue<Integer>(5);
               pq.offer(score);
               map.put(id, pq);
           }else{
               PriorityQueue<Integer> pq = map.get(id);
               pq.offer(score);
               if(pq.size() > 5){
                   pq.poll();
               }
               map.put(id, pq);
           }
       }
        
        int index = 0;
        
        int[][] res = new int[map.size()][2];
        
       for(int id : map.keySet()){
           
           res[index][0] = id;
        
           PriorityQueue<Integer> pq = map.get(id);
           int sum = 0;
           int size = pq.size();
           
           while(!pq.isEmpty()){
               sum+= pq.poll();
           }
         
           res[index][1] = sum/size;
           
           index++;
           
       }
        
      
        return res;
       
    }
}

分析

本题使用PriorityQueue是十分自然的:

1>PriorityQueue是一种无界的,线程不安全的队列
2>PriorityQueue是一种通过数组实现的,并拥有优先级的队列
3>PriorityQueue存储的元素要求必须是可比较的对象, 如果不是就必须明确指定比较器

参考下面这篇文章:

https://www.jianshu.com/p/f1fd9b82cb72

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值