Given an array of meeting time intervals consisting of start and end
times [[s1,e1],[s2,e2],…] (si < ei), find the minimum number of
conference rooms required.For example, Given [[0, 30],[5, 10],[15, 20]], return 2.
这道题目比较有意思,记录一下大神的解法。
解法1 使用有序map
在Java中,TreeMap是有序map,对键进行了排序。
解题的思路是,用map记录房间瞬时的使用情况。
一个区间的开始,代表开启了一间房,结束,表明关闭了一间房。
我们遍历intervals,记录每一个时刻的开始数目和结束数目,然后按键从小到大遍历map,相当于遍历整个时间轴。我们需要的最小房间数,就是满足每个瞬时房间需求的房间数目。
代码如下:
public int minMeetingRoomsWithmap(Interval[] intervals) {
TreeMap<Integer, Integer> map = new TreeMap<>();
for (Interval interval : intervals) {
map.put(interval.start, map.getOrDefault(interval.start, 0) + 1);
map.put(interval.end, map.getOrDefault(interval.end, 0) - 1);
}
int res = 0,mid = 0;
for (int m : map.values()) {
res = Math.max(res, mid += m);
}
return res;
}
解法2,使用最小堆
首先,按照开始时间排序,然后用一个heap记录每个会议室的使用时间。同时heap是一个最小堆,可以取出最早结束的会议。
一开始,将最早开始的会议安排一个房间进heap。
之后遍历排序后的intervals。每当有一个新的会议要开始,从最小堆heap中查看最先要结束的会议,如果时间不冲突,直接将该会议室的结束时间扩展。如果时间冲突,安排一个新的会议室,推进heap。
public int minMeetingRooms(Interval[] intervals) {
if (intervals == null || intervals.length == 0) return 0;
Arrays.sort(intervals, (a, b) -> a.start - b.start);
PriorityQueue<Interval> heap = new PriorityQueue<>((a, b) -> a.end - b.end);
heap.add(intervals[0]);
for (int i = 1;i<intervals.length;i++) {
Interval now = heap.poll();
if (intervals[i].start >= now.end) {
//时间不冲突,原最早结束的会议室,时间扩展即可。
now.end = intervals[i].end;
}else {
//时间冲突,添加新的会议室。
heap.offer(intervals[i]);
}
heap.offer(now);
}
return heap.size();
}