会议室 III
难度:
标签:
题目描述
代码结果
运行时间: 227 ms, 内存: 48.5 MB
/*
题目思路:
1. 对会议数组进行排序,按开始时间升序排列。
2. 使用两个PriorityQueue,一个用于追踪空闲会议室,另一个用于追踪占用的会议室。
3. 初始化一个数组用于记录每个会议室的使用次数。
4. 遍历所有会议,检查有无可用会议室。若无可用会议室,则将会议延期。
5. 更新会议室的使用情况和使用次数,最后返回使用次数最多的会议室编号。
*/
import java.util.*;
import java.util.stream.IntStream;
public class MeetingRoomSchedulerStream {
public int mostBooked(int n, int[][] meetings) {
Arrays.sort(meetings, Comparator.comparingInt(a -> a[0]));
PriorityQueue<Integer> availableRooms = IntStream.range(0, n).boxed().collect(Collectors.toCollection(PriorityQueue::new));
PriorityQueue<int[]> occupiedRooms = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
int[] roomUsage = new int[n];
for (int[] meeting : meetings) {
while (!occupiedRooms.isEmpty() && occupiedRooms.peek()[0] <= meeting[0]) {
availableRooms.add(occupiedRooms.poll()[1]);
}
if (availableRooms.isEmpty()) {
int[] earliest = occupiedRooms.poll();
occupiedRooms.add(new int[]{earliest[0] + (meeting[1] - meeting[0]), earliest[1]});
} else {
int room = availableRooms.poll();
roomUsage[room]++;
occupiedRooms.add(new int[]{meeting[1], room});
}
}
return IntStream.range(0, n).reduce((a, b) -> roomUsage[a] >= roomUsage[b] ? a : b).orElse(0);
}
}
解释
方法:
该题解采用了优先队列(堆)来管理会议室的分配和追踪会议的结束时间。首先,将会议按照开始时间排序,以保证处理时遵循题目要求的优先级。定义两个堆,`idle` 用来存放当前空闲的会议室编号,`using` 用来存放正在使用中的会议室及其结束时间。对每场会议,首先释放所有已经结束的会议室到空闲堆中。如果此时还有空闲会议室,就分配编号最小的会议室;如果没有空闲会议室,则选择最早结束的会议室,并将当前会议延后到该会议室空闲时开始。每次会议分配后,更新会议室使用次数,并将其结束时间和编号加入使用中堆。最后,遍历使用次数数组,找到使用次数最多的会议室编号。
时间复杂度:
O(m log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在处理会议时,为什么首先需要释放所有已结束的会议室,而不是直接查看是否有空闲会议室?
▷🦆
题解中提到,如果所有会议室都被占用,则选择最早结束的会议室延后当前会议。请问这样的处理方式是否会影响到其他后续会议的安排?
▷🦆
在找出使用最多的会议室时,代码是如何确保在计数相同的情况下返回编号最小的会议室的?
▷🦆
请问在所有会议室空闲时,选择哪个会议室进行分配是否会对算法的效率或结果产生影响?
▷