2026/1/14 1:29:03
网站建设
项目流程
邯郸普通网站建设,2023年1月热点新闻事件,怎么找到合适的网站建设商,如何建设一个视频网站前言#xff1a;这是来自likou的一道算法题#xff0c;使用双堆模拟解法这是一个会议室资源调度问题#xff0c;核心是按照特定规则将会议分配给会议室#xff0c;需要考虑延期机制和优先级。题目#xff1a;给你一个整数 n #xff0c;共有编号从 0 到 n - 1 的 n 个会议…前言这是来自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 1001 meetings.length 105meetings[i].length 20 starti endi 5 * 105starti 的所有值 互不相同题目分析核心挑战:处理延期会议哪些会议在等待维护会议室状态哪些会议室空闲何时释放优先级排序延期会议按原开始时间排序时间推进模拟整个时间线上的事件事件驱动关注会议室释放时间和会议开始时间数据结构选择维护空闲会议室优先选择编号小的维护进行中的会议知道何时结束维护等待队列按原开始时间排序时间推进策略跳到下一个关键时间点会议开始或会议室释放算法逻辑框架按原开始时间排序所有会议初始化所有会议室为空闲按时间顺序处理统计每个会议室的会议次数返回举办会议次数最多且编号最小的会议室代码class Solution { public int mostBooked(int n, int[][] meetings) { Arrays.sort(meetings,(a,b) - a[0] - b[0]); PriorityQueueInteger freerooms new PriorityQueue(); for(int i 0;in;i){ freerooms.offer(i); } PriorityQueuelong[] 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;in;i){ if(cnt[i] cnt[ans]){ ans i; } } return ans; } }代码分析1、排序对meetings进行排序以开始时间的高低排序Arrays.sort(meetings,(a,b) - a[0] - b[0]);2、初始化定义两个队列堆队列freerooms来存空闲的会议室编号并初始化队列using来存使用的会议室编号并且存的数组结束时间会议室编号PriorityQueueInteger freerooms new PriorityQueue(); for(int i 0;in;i){ freerooms.offer(i); } PriorityQueuelong[] 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、提交并记录把这个会议室加入队列并把这个会议室的使用次数加1using.offer(new long[]{end,i}); cnt[i];4、循环找最小值循环meetings得到cnt数组各个会议室的使用次数这个时候循环比较得到使用次数最多的那间会议室int ans 0; for(int i 1;in;i){ if(cnt[i] cnt[ans]){ ans i; } }结语这是一个很经典的双堆模拟问题来自力扣希望对你有帮助