LeetCode——5703. 最大平均通过率(Maximum Average Pass Ratio)[中等]——分析及代码(Java)

LeetCode——5703. 最大平均通过率[Maximum Average Pass Ratio][中等]——分析及代码[Java]

一、题目

一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10^-5 以内的结果都会视为正确结果。

示例 1:

输入:classes = [[1,2],[3,5],[2,2]], extraStudents = 2
输出:0.78333
解释:你可以将额外的两个学生都安排到第一个班级,平均通过率为 (3/4 + 3/5 + 2/2) / 3 = 0.78333 。

示例 2:

输入:classes = [[2,4],[3,9],[4,5],[2,10]], extraStudents = 4
输出:0.53485

提示:

  • 1 <= classes.length <= 10^5
  • classes[i].length == 2
  • 1 <= passi <= totali <= 10^5
  • 1 <= extraStudents <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-average-pass-ratio
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析及代码

1. 优先队列(堆)

(1)思路

设计一个降序的优先队列(最大堆),将各个班级按照 添加一名学生后通过率的增加值 进行排序,依次向提升效果最显著的班级安排学生,直至完成。

(2)代码

class students {
    
    //表示班级,为避免class关键字冲突写成students
    public double rate;//表示添加一名学生后通过率的增加值,为简化题解,直接设为public
    public int pass, total;//记录当前班级通过人数、总人数,便于计算
    public students(double rate, int pass, int total) {
    
    
        this.rate = rate;
        this.pass = pass;
        this.total = total;
    }
}

class Solution {
    
    
    public double maxAverageRatio(int[][] classes, int extraStudents) {
    
    
        int n = classes.length;
        PriorityQueue<students> maxheap = new PriorityQueue<students>(n, new Comparator<students>() {
    
    //基于通过率提升值排序的最大堆
            public int compare(students a, students b) {
    
    
                if (b.rate - a.rate > 0)
                    return 1;
                return -1;
            }
        });
        for (int i = 0; i < n; i++) {
    
    //初始化,将所有班级放入堆中
            int pass = classes[i][0], total = classes[i][1];
            double rate = ((double)(pass + 1)) / (total + 1) - ((double)pass / total);//计算通过率增加值
            maxheap.add(new students(rate, pass, total));
        }
        
        //不断向提升效果最显著的班级安排学生
        for (int i = 0; i < extraStudents; i++) {
    
    
            students change = maxheap.poll();
            int pass = change.pass + 1, total = change.total + 1;
            double newrate = ((double)(pass + 1)) / (total + 1) - ((double)pass / total);
            maxheap.add(new students(newrate, pass, total));
        }

        //计算总通过率
        double rateSum = 0;
        for (int i = 0; i < n; i++) {
    
    
            students student = maxheap.poll();
            int pass = student.pass, total = student.total;
            double rate = ((double) pass / total);
            rateSum += rate;
        }
        return rateSum / n;//计算平均通过率
    }
}

(3)结果

执行用时 :400 ms,在所有 Java 提交中击败了 100.00% 的用户;
内存消耗 :86.6 MB,在所有 Java 提交中击败了 100.00% 的用户。
(目前提交用户量不足,暂无排名)

三、其他

暂无。

猜你喜欢

转载自blog.csdn.net/zml66666/article/details/114807538