Leetcode 每日一题:Meeting Rooms II

Leetcode 每日一题:Meeting Rooms II_第1张图片

写在前面:

今天我们来看的题目是 Meeting Room 进阶版 Meeting Room II。推荐没有做过 Leetcode 的麻油们从 Meeting Room I 先开始,这样可以更好的思考 Meeting Room 场景下的思路

Meeting Room I 题目地址:https://leetcode.com/problems/meeting-rooms/description/icon-default.png?t=N7T8https://leetcode.com/problems/meeting-rooms/description/

这道题目看起来是一个合并区间相关的问题,但在对 Meeting Room 这个场景的巧妙思考下,我们可以利用更高效的数据结构 Minheap 来解决这个问题。我们来一起看看吧!

题目介绍:

 题目信息:

  • 题目地址:https://leetcode.com/problems/meeting-rooms-ii/description/
  • 题目类型:Array,PriorityQueue
  • 题目难度:Medium
  • 题目来源:Google 高频面试真题

题目问题:

  • 给定一组数组,每个元素是一个 长度为 2 的固定数组,代表一个 Meeting 的开始和结束时间
  • 每一个 Meeting Room 只能容纳一个 Meeting 同时进行
  • 问如果需要将所有会议全部安排,最少需要多少个 Meeting Rooms
  • 例子:
    • [[1, 30], [5, 10], [30, 50]] 
    • 代表第一会议从单位 10 开始,第二个从单位5 开始,etc
    • [1, 30] 和 [5, 10] 存在重复区间,则需要两个不同的 Meeting Room 才能安排
    • [1, 30] 和 [30, 50] 之间不存在重复区间,可以在相同的 Meeting Room 进行

题目想法:

Meeting Room 场景思考:

  • 对于 Meeting 是否有 Conflict,我们只需要看同一个 room 前一个 Meeting 的结束时间和后一个 Meeting 的开始时间即可
  • 因为时间是有序的,所以我们在 schedule 的时候最好也将我们的 Meeting 发生时间进行正向排序,更契合我们真实的场景
  • 对于已经 Schedule 的 Meeting,我们只 care 他们的 endTime 就行。而在所有的 Meeting Room 当中,我们只需要和最早结束的 endTime 进行对比就行。
    • 因为如果这个 最早的 Meeting 已经结束,则我们直接 schedule 到这个位置
    • 如果这个最早的 Meeting 没结束,则我们肯定需要一个新的 Meeting room 去 schedule 当前 meeting
    • 我们之前的排序保证了我们每一次新 schedule 的 meeting 都是最早开始的,意味着我们每次都在尝试找到最优解 - 让每一个 room 内的 meeting 间隔最短,可容纳的 Meeting Room 越多
  • 对于已经 Schedule 的 Meeting Room,我们可以针对他们的 endTime 用 minheap 进行排序,每次只需要和最上面的比对就可以
  • 如果比最早结束的 Meeting 开始晚,则我们可以在相同房间安排,反之需要新房间

MinHeap 在场景下的使用:

对于 Minheap,我们每次比较当前 Meeting 的开始时间和 Minheap head 的结束时间:

  1. 如果可以 schedule,则 pop 掉头部结束时间,将当前 Meeting 的结束时间重新放进 Minheap,这就可以理解为使用了同一 Meeting Room
  2. 如果不可以schedule,则直接将当前 meeting 的结束时间放进 Minheap,这可以理解为需要一个新的 Meeting Room 
  3. 最后整个 minHeap 的长度代表了需要的 Meeting Room 最小总数

题目解法:

  • 如果 interval 长度为 1, 只有一个 meeting,直接 return 1
  • 按照每个数组第一位(start time) 对整个数组进行排序
  • 定义 Minheap,先放入第一个 Meeting 的 endTime
  • 遍历所有 Meeting interval:
    • 将当前 interval 的 start time 与 Minheap.top,也就是最早的 endtime 做比较
    • 如果比最早的 endtime 结束的晚
      • 将 top 从 Minheap 中剔除
      • 将 当前 meeting 的 endtime 加入 Minheap 中
    • else:
      • 将当前 meeting 的 endtime 加入 Minheap 中
  • 返回 priority queue 最终的长度
  • Tip: 在只有 Maxheap 的语言中(如 C++),如果要使用 minheap,可以将所有元素值 * (-1)

题目代码:

class Solution {
public:
    int minMeetingRooms(vector>& intervals) {
        if(intervals.size() == 1) return 1;
        
        //sort the meeting by start time
        sort(intervals.begin(), intervals.end());
        
        //initiate the room storage, each room stores the end time as min-heap
        //if the smallest endtime cannot satisfied, we cannot proceed in this room. 
        priority_queue roomsEndings;
        roomsEndings.push(intervals[0][1] * (-1));  //only store the end-time as minheap
        
        //for every meeting, check if we can fit in ended room
        for(int i = 1; i < intervals.size(); i++){
            //we can fit in, then update the room's ending time with the current one
            if(intervals[i][0] >= roomsEndings.top() * (-1)){
                roomsEndings.pop();
            }
            roomsEndings.push(intervals[i][1] * (-1));
        }
        return roomsEndings.size();
    }
};

1. Runtime: O(nlogn) + O(n * logn) = O(nlogn)

2. Space: O(n)

你可能感兴趣的:(leetcode,算法,职场和发展)