当前位置: 首页 > news >正文

【LeetCode】1792. 最大平均通过率(康复-T1)

题目描述

最大平均通过率
在这里插入图片描述
这道题的相关标签:贪心、堆、数组

题目解读

根据题目意思的解读,是分配学生到班级,然后尽可能的提高班级的平均通过率。
从贪心的角度分析,将一个学生分配,依次比较分配到的每一个班级,然后比较分配前与分配后的通过率,提升最大的,就是提升通过率最高的

从数学的角度分析,问题是Avg=1N∑i=0NaiAvg=\frac{1}{N}\sum_{i=0}^{N}a_iAvg=N1i=0Nai,而每一次增加一个一定通过的学生,结果等于1N(∑i=0Nai+Δ)\frac{1}{N}(\sum_{i=0}^{N}{a_i+\Delta})N1(i=0Nai+Δ),其中Δ\DeltaΔ代表每一次学生进入班级导致通过率提升,所以,问题的目标是max(1N∑i=0Nai+Δ)max(\frac{1}{N}\sum_{i=0}^{N}a_i+\Delta)max(N1i=0Nai+Δ),进一步可得1N∑i=0Nai+max(Δ)\frac{1}{N}\sum_{i=0}^{N}a_i+max(\Delta)N1i=0Nai+max(Δ)
所以,只需要保证每一次的选择Δ\DeltaΔ最大即可。

在代码实现上,要依次进行extraStudents次循环,每一个学生需要比较进入每一个班级,所带来了通过率的提升,然后每一次选取最大的,更新班级的人数,直到循环结束。
所以,一个大循环extraStudents,内部循环一个班级,时间复杂度分析O(E×N)O(E \times N)O(E×N)

代码实现

v1:数组

class Solution {
public:double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {int N = classes.size(); // N个班级vector<int> record = vector(N,0);auto classes_cp(classes);for (int i = 0; i < extraStudents; i++) {float max_delta = 0;int r_idx = 0;for (int j = 0; j < N; j++) {float delta =(float)(classes_cp[j][0] + 1) / (1.0 * (classes_cp[j][1] + 1)) -(float)(classes_cp[j][0]) / (1.0 * (classes_cp[j][1]));if(max_delta<=delta){max_delta=delta;r_idx=j;}}classes_cp[r_idx][0]+=1;classes_cp[r_idx][1]+=1;}double p_ratio = 0;for(int i=0;i<N;i++){p_ratio += (double)(classes_cp[i][0]) / (double)(classes_cp[i][1]);}return p_ratio / N;}
};

但是,这个版本的代码,在数据量大时,是无法通过,超时,因为是嵌套循环。
其中,存在大量的重复计算。
每一次将学生加入班级,N个班级都会重复计算一遍用来比较增长率,优化的方向:

减少重复计算,消耗空间资源来记录其余班级的增长率,避免每一次都需要重新计算

可以使用大根堆,其树形结构可以快速计算出集合中最大的,如果使用数组记录,还得进行排序,比较复杂,大根堆是较优秀的选择。

v2:大根堆

class Solution {
public:double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {int N = classes.size(); // N个班级priority_queue<pair<float, pair<int, int>>> pq;for (int i = 0; i < N; i++) {float delta =(float)(classes[i][0] + 1) / (1.0 * (classes[i][1] + 1)) -(float)(classes[i][0]) / (1.0 * (classes[i][1]));auto ele =make_pair(delta, make_pair(classes[i][0], classes[i][1]));pq.emplace(ele);}for (int i = 0; i < extraStudents; i++) {auto p = pq.top();pq.pop();int pass = p.second.first + 1;int total = p.second.second + 1;//cout<<pass<<"/"<<total<<endl;float delta = (float)(pass + 1) / (1.0 * (total + 1)) -(float)(pass) / (1.0 * (total));auto ele = make_pair(delta, make_pair(pass, total));pq.emplace(ele);}double p_ratio = 0;while(!pq.empty()){auto p = pq.top();pq.pop();int pass = p.second.first;int total = p.second.second;p_ratio += (1.0 * pass) / (1.0 * (total));}return p_ratio / N;}
};

建议:每次面对问题,先建模、列公式进行分析,才能快速发现问题

http://www.dtcms.com/a/362615.html

相关文章:

  • 校企合作| 长春大学旅游学院副董事长张海涛率队到访卓翼智能,共绘无人机技术赋能“AI+文旅”发展新蓝图
  • DAG与云计算任务调度优化
  • 【android bluetooth 协议分析 21】【ble 介绍 3】【ble acl Supervision Timeout 介绍】
  • 无人机系统理论基础(有课件)
  • 无人机小尺寸RFSOC ZU47DR板卡
  • 无人机传感器技术要点与难点解析
  • 【无人机三维路径规划】基于遗传算法GA结合粒子群算法PSO无人机复杂环境避障三维路径规划(含GA和PSO对比)研究
  • 基于YOLOv4的无人机视觉手势识别系统:从原理到实践
  • C++面试题
  • 股指期货是股市下跌的原罪,还是风险对冲好帮手?
  • 什么是 DNSSEC?
  • 面试tips--MySQLRedis--Redis 有序集合用跳表不用B+树 MySQL用B+树作为存储引擎不用跳表:原因如下
  • 278-基于Django的协同过滤旅游推荐系统
  • 详解Grafana k6 的阈值(Thresholds)
  • os.path:平台独立的文件名管理
  • sql执行过程
  • Tomcat 全面指南:从目录结构到应用部署与高级配置
  • Java-Spring入门指南(一)Spring简介
  • WPF曲线自定义控件 - CurveHelper
  • 大模型是如何“学会”思考的?——从预训练到推理的全过程揭秘
  • 【完整源码+数据集+部署教程】PHC桩实例分割系统源码和数据集:改进yolo11-Faster-EMA
  • 无需服务器,免费、快捷的一键部署前端 vue React代码--PinMe
  • 搭建分布式Hadoop集群[2025] 实战笔记
  • 【golang长途旅行第36站】golang操作Redis
  • 【自记】Python 中 简化装饰器使用的便捷写法语法糖(Syntactic Sugar)示例
  • ARM汇编记忆
  • 【53页PPT】华为制造行业数字化转型工业互联网智能制造解决方案(附下载方式)
  • MySQL事务+MVCC(精简版,包教包废)
  • 2025华为最值得入的耳机,真的赢麻了!
  • 结构抗震与土木工程研究