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();
}