leetcode
leetcode 2051 ~ 2100
会议室 III

会议室 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)

代码细节讲解

🦆
在处理会议时,为什么首先需要释放所有已结束的会议室,而不是直接查看是否有空闲会议室?
在处理会议时,首先释放所有已结束的会议室是必要的,因为只有这样我们才能获得最准确的关于会议室当前状态的信息。如果不先更新会议室的状态,我们可能会错误地认为没有空闲的会议室可用,从而导致不必要的会议延误或错误的会议室分配。这种方式确保了算法能够根据实际情况做出最合理的决策。
🦆
题解中提到,如果所有会议室都被占用,则选择最早结束的会议室延后当前会议。请问这样的处理方式是否会影响到其他后续会议的安排?
是的,这种处理方式可能会影响到其他后续会议的安排。当所有会议室都被占用时,选择最早结束的会议室并延后当前会议的开始时间,这会导致该会议室的可用时间推迟,进而可能影响排在后面的会议。然而,这是一种权衡策略,用于在资源紧张时尽量减少对总体会议安排的影响。
🦆
在找出使用最多的会议室时,代码是如何确保在计数相同的情况下返回编号最小的会议室的?
在代码中,通过遍历会议室使用次数的数组并比较每个会议室的使用次数来确定使用次数最多的会议室。如果发现有多个会议室的使用次数相同,代码会保留先前找到的那个会议室的编号,因为它是首先遇到的且编号较小的。这是因为数组是按索引(即会议室编号)顺序遍历的,所以最先找到的最大计数值对应的会是最小的编号。
🦆
请问在所有会议室空闲时,选择哪个会议室进行分配是否会对算法的效率或结果产生影响?
在所有会议室空闲时,选择哪个会议室进行分配实际上不会对算法的效率产生显著影响,因为所有会议室都可用并且等效。但在实际应用中,可能会根据会议室的物理位置或其他资源因素选择最合适的会议室。在算法实现中,通常选择编号最小的会议室,这样做是为了保持处理的一致性和简单性。

相关问题