news 2026/5/23 18:26:16

力扣--2402. 会议室 III(Java)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣--2402. 会议室 III(Java)

前言:

这是来自likou的一道算法题,使用双堆模拟解法

这是一个会议室资源调度问题,核心是按照特定规则将会议分配给会议室,需要考虑延期机制和优先级。


题目:

给你一个整数 n ,共有编号从 0 到 n - 1 的 n 个会议室。

给你一个二维整数数组 meetings ,其中 meetings[i] = [starti, endi] 表示一场会议将会在 半闭 时间区间 [starti, endi) 举办。所有 starti 的值 互不相同 。

会议将会按以下方式分配给会议室:

1、每场会议都会在未占用且编号 最小 的会议室举办。
2、如果没有可用的会议室,会议将会延期,直到存在空闲的会议室。延期会议的持续时间和原会议持续时间 相同 。
3、当会议室处于未占用状态时,将会优先提供给原 开始 时间更早的会议。
返回举办最多次会议的房间 编号 。如果存在多个房间满足此条件,则返回编号 最小 的房间。

半闭区间 [a, b) 是 a 和 b 之间的区间,包括 a 但 不包括 b 。

示例 1:

输入:n = 2, meetings = [[0,10],[1,5],[2,7],[3,4]]
输出:0
解释:
- 在时间 0 ,两个会议室都未占用,第一场会议在会议室 0 举办。
- 在时间 1 ,只有会议室 1 未占用,第二场会议在会议室 1 举办。
- 在时间 2 ,两个会议室都被占用,第三场会议延期举办。
- 在时间 3 ,两个会议室都被占用,第四场会议延期举办。
- 在时间 5 ,会议室 1 的会议结束。第三场会议在会议室 1 举办,时间周期为 [5,10) 。
- 在时间 10 ,两个会议室的会议都结束。第四场会议在会议室 0 举办,时间周期为 [10,11) 。
会议室 0 和会议室 1 都举办了 2 场会议,所以返回 0 。

示例 2:

输入:n = 3, meetings = [[1,20],[2,10],[3,5],[4,9],[6,8]]
输出:1
解释:
- 在时间 1 ,所有三个会议室都未占用,第一场会议在会议室 0 举办。
- 在时间 2 ,会议室 1 和 2 未占用,第二场会议在会议室 1 举办。
- 在时间 3 ,只有会议室 2 未占用,第三场会议在会议室 2 举办。
- 在时间 4 ,所有三个会议室都被占用,第四场会议延期举办。
- 在时间 5 ,会议室 2 的会议结束。第四场会议在会议室 2 举办,时间周期为 [5,10) 。
- 在时间 6 ,所有三个会议室都被占用,第五场会议延期举办。
- 在时间 10 ,会议室 1 和 2 的会议结束。第五场会议在会议室 1 举办,时间周期为 [10,12) 。
会议室 1 和会议室 2 都举办了 2 场会议,所以返回 1 。

提示:

1 <= n <= 100
1 <= meetings.length <= 105
meetings[i].length == 2
0 <= starti < endi <= 5 * 105
starti 的所有值 互不相同


题目分析:

核心挑战:

  1. 处理延期会议:哪些会议在等待
  2. 维护会议室状态:哪些会议室空闲,何时释放
  3. 优先级排序:延期会议按原开始时间排序
  4. 时间推进:模拟整个时间线上的事件

事件驱动:

关注会议室释放时间和会议开始时间

数据结构选择:

  1. 维护空闲会议室(优先选择编号小的)
  2. 维护进行中的会议(知道何时结束)
  3. 维护等待队列(按原开始时间排序)

时间推进策略:

跳到下一个关键时间点(会议开始或会议室释放)


算法逻辑框架

  1. 按原开始时间排序所有会议
  2. 初始化所有会议室为空闲
  3. 按时间顺序处理
  4. 统计每个会议室的会议次数
  5. 返回举办会议次数最多且编号最小的会议室

代码:

class Solution { public int mostBooked(int n, int[][] meetings) { Arrays.sort(meetings,(a,b) -> a[0] - b[0]); PriorityQueue<Integer> freerooms = new PriorityQueue<>(); for(int i = 0;i<n;i++){ freerooms.offer(i); } PriorityQueue<long[]> using = new PriorityQueue<>( (a,b) ->a[0] != b[0] ? Long.compare(a[0],b[0]) : Long.compare(a[1],b[1]) ); int[] cnt = new int[n]; for(int[] m : meetings){ long start = m[0]; long end = m[1]; while(!using.isEmpty() && using.peek()[0] <= start){ freerooms.offer((int) using.poll()[1]); } int i; if(!freerooms.isEmpty()){ i = freerooms.poll(); }else{ long[] p = using.poll(); end += p[0] - start; i = (int) p[1]; } using.offer(new long[]{end,i}); cnt[i]++; } int ans = 0; for(int i = 1;i<n;i++){ if(cnt[i] > cnt[ans]){ ans = i; } } return ans; } }

代码分析:

1、排序

对meetings进行排序,以开始时间的高低排序

Arrays.sort(meetings,(a,b) -> a[0] - b[0]);

2、初始化

定义两个队列(堆),队列freerooms来存空闲的会议室编号,并初始化,队列using来存使用的会议室编号,并且存的数组(结束时间,会议室编号)

PriorityQueue<Integer> freerooms = new PriorityQueue<>(); for(int i = 0;i<n;i++){ freerooms.offer(i); } PriorityQueue<long[]> using = new PriorityQueue<>((a,b) ->a[0] != b[0] ? Long.compare(a[0],b[0]) : Long.compare(a[1],b[1]));

3、逻辑实现

int[] cnt = new int[n]; for(int[] m : meetings){ long start = m[0]; long end = m[1]; while(!using.isEmpty() && using.peek()[0] <= start){ freerooms.offer((int) using.poll()[1]); } int i; if(!freerooms.isEmpty()){ i = freerooms.poll(); }else{ long[] p = using.poll(); end += p[0] - start; i = (int) p[1]; } using.offer(new long[]{end,i}); cnt[i]++; }

1、在start时刻空闲的会议室

如果在使用的会议室里面存在结束时间小于当前的开始时间,则需要踢出队列,并把这个会议室加入到空闲会议室队列

while(!using.isEmpty() && using.peek()[0] <= start){ freerooms.offer((int) using.poll()[1]); }

2、判断

如果空闲会议室队列不为空,就说明里面有会议室可以使用,就取最小的会议室供后面使用

如果为空,就说明没有空闲的会议室,则弹出一个最早结束的会议室供使用,并调整结束时间

int i; if(!freerooms.isEmpty()){ i = freerooms.poll(); }else{ long[] p = using.poll(); end += p[0] - start; i = (int) p[1]; }

3、提交,并记录

把这个会议室加入队列,并把这个会议室的使用次数加1

using.offer(new long[]{end,i}); cnt[i]++;

4、循环找最小值

循环meetings,得到cnt数组,各个会议室的使用次数,这个时候循环比较,得到使用次数最多的那间会议室

int ans = 0; for(int i = 1;i<n;i++){ if(cnt[i] > cnt[ans]){ ans = i; } }

结语:

这是一个很经典的双堆模拟问题,来自力扣,希望对你有帮助!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 5:39:14

无需修改代码:如何用TensorRT插件式接入现有AI系统?

无需修改代码&#xff1a;如何用TensorRT插件式接入现有AI系统&#xff1f; 在当今高并发、低延迟的AI服务场景中&#xff0c;一个常见的困境是&#xff1a;模型已经训练得足够准确&#xff0c;业务逻辑也已稳定运行&#xff0c;但面对不断增长的请求量&#xff0c;推理性能却成…

作者头像 李华
网站建设 2026/5/23 11:51:13

Keil调试教程:STM32实时变量监控方法

Keil调试实战&#xff1a;手把手教你精准监控STM32运行时变量 你有没有遇到过这样的场景&#xff1f; PID控制输出突然震荡&#xff0c;但串口打印的日志却风平浪静&#xff1b;DMA传输的数据莫名其妙被覆盖&#xff0c;翻遍代码也找不到源头&#xff1b;某个全局标志位在中断…

作者头像 李华
网站建设 2026/5/17 1:51:59

快速理解STM32F4固件包结构与用途

深入理解STM32F4固件包&#xff1a;从结构到实战的完整指南 在嵌入式开发的世界里&#xff0c;时间就是竞争力。当你拿到一块崭新的STM32F4开发板&#xff0c;面对密密麻麻的引脚和复杂的外设手册时&#xff0c;是否曾感到无从下手&#xff1f;如何在最短时间内点亮LED、串口打…

作者头像 李华
网站建设 2026/5/16 12:13:22

短视频内容审核自动化:TensorRT加速视觉语言模型

短视频内容审核自动化&#xff1a;TensorRT加速视觉语言模型 在如今的短视频时代&#xff0c;每天有数亿分钟的新视频涌入主流平台。面对如此海量的内容&#xff0c;人工审核早已不堪重负——不仅成本高昂&#xff0c;更无法满足实时性与覆盖率的要求。于是&#xff0c;自动化内…

作者头像 李华
网站建设 2026/5/22 10:14:39

TI C2000电机控制器ADC采样精度优化操作指南

TI C2000电机控制器ADC采样精度优化实战指南在高性能电机控制领域&#xff0c;“看得清”才能“控得准”。电流和电压的实时感知能力&#xff0c;直接决定了FOC&#xff08;磁场定向控制&#xff09;算法能否精准解耦、转矩脉动是否可控、系统效率能不能拉到极限。而这一切的基…

作者头像 李华