刷题的日常-最大平均通过率

114 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情

刷题的日常-2023年2月19号

一天一题,保持脑子清爽

最大平均通过率

来自leetcode的 1792 题,题意如下:

一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes,其中classes[i] = [passi, totali],表示你提前知道了第i个班级总共有totali个学生,其中只有passi`个学生可以通过考试。

给你一个整数extraStudents,表示额外有extraStudents个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这extraStudents个学生每人都安排一个班级,使得 所有班级的 平均通过率 最大`。

一个班级的通过率等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。

请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在10^5以内的结果都会视为正确结果。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出一个二维数组,二维数组里的每一个元素代表 分子 和 分母
  • 再给出一个数,要求将数分配给二维数组
  • 将分子 分母的平均比值最大化

做题思路

题意好理解,要将平均通过率拉高,就要拉高每个平均班级的通过率。那么问题来了,只要分配的学生能通过考试,那么就一定能拉高通过率。这时问题就变成了分配给哪个班级最合适。

根据分析,我们每次分配其实都要找一个 通过率 上升最大的班级进行分配,是一种贪心的做法。每一个待分配的学生,都需要找到当前通过率变化最大的一个班级放进去,这样就能保证最后的平均值是最大的。

步骤如下:

  • 开辟一个优先级队列,排序规则是 当前通过率 和 加一个学生之后的通过率之差 从大到小进行排序
  • 将所有班级放入队列中
  • 对每个学生进行分配
  • 每次都从队列取出顶端元素,将学生分配出去,再放回队列
  • 最后计算总比值并返回结果

代码实现

代码实现如下:

image.png

image.png