Meeting Rooms II
Question:
思路:
这道题呢,是meeting room的变形,难点在于 我们不太容易确认当两个meeting产生conflict的时候, 是否前一个meeting已经结束了, 如果结束了, 就不需要再追加新的room, 如果没结束就得再增加一个meeting room.
此时我们的想法就应该是, 运用一个heap 存储正在进行的meeting, 然后每次当要加入下一个meeting的时候, 运用heap的性质,判断heap里结束最早的meeting是否 在下一个要加入的meeting 开始之前已经结束, 如果是, 那么就可以把这个meeting 从heap里移除并且加新的meeting, 此时heap里meeting数量不变 不需要增加更多的room.
反之,如果新的meeting 开始了, heap里没有meeting 结束, 那么就得再加进heap里, heap的size增加, 进而需要的room数量增加.
为什么一定要用heap呢, 因为单单Queue的性质是不够的.
heap 可以自动排序,把meeting end 最早的排在前面, Queue 只能按顺序添加, 有可能end 更早的meeting 比end 更晚的meeting 早添加, 这样的话我们还得手动在queue里寻找end 最早的meeting.
这是基础的思路.
code
class Solution {
public int minMeetingRooms(int[][] intervals) {
Arrays.sort(intervals, (x,y)->Integer.compare(x[0] , y[0]));
int rooms = 1;
PriorityQueue<int[]> meeting = new PriorityQueue<>((x,y) -> Integer.compare(x[1] , y[1]));
meeting.offer(intervals[0]);
for(int i = 1;i < intervals.length; ++i){
while(!meeting.isEmpty()){
int[] front = meeting.peek();
if(intervals[i][0] < front[1]){
break;
} else{
meeting.poll();
}
}
meeting.offer(intervals[i]);
rooms = Math.max(meeting.size(), rooms);
}
return rooms;
}
}
还有一个思路比较nb, 就是直接把所有meeting加进heap里。
heap 里存int[], 把每一个meeting的start time 当作int[0], 数字1 当作int[1] 储存, 而对于end time, 数字-1当作int[1], 然后再按照所有的start 和 end的大小排序, 当遇上start和end时间相同,那就把start Time先排在前面
之后iterate heap. room的数量随着heap po出来的element做+1或者-1
什么意思呢?
就是说每次有一个start, 我们的room就需要+1,
当有一个end了, 我们的room就-1.
因为顺序是排好的. 所以按照顺序+1-1就可以遇到需要最多room的时刻.
code
class Solution {
public int minMeetingRooms(int[][] intervals) {
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));
int max = 0;
for(int[] interval : intervals) {
int start = interval[0];
int end = interval[1];
pq.offer(new int[]{start, 1});
pq.offer(new int[]{end, -1});
}
int count = 0;
while(!pq.isEmpty()) {
count+=pq.poll()[1];
if(count > max) max = count;
}
return max;
}
}