LeetCode——1792. 最大平均通过率[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% 的用户。
(目前提交用户量不足,暂无排名)
三、其他
暂无。