leetcode:253. 会议室 II 会员题
lintcode:919 · 会议室 II

题目

给你一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] = [starti, endi] ,为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。

示例:

  1. 输入:intervals = [[0,30],[5,10],[15,20]]
  2. 输出:2
  1. 输入:intervals = [[7,10],[2,4]]
  2. 输出:1

解答 & 代码

参考:扫描线技巧:安排会议室,但是这篇博客里没有解释代码含义。因此本文对代码进行了详细注释

本题是要计算同一时刻最多有多少会议在同时进行。
双指针解法:只需要注意什么时候开始会议、什么时候散会。将开始会议、散会的时间分为两个数组,通过滑动指针的方式,判断同时在开会的会议数量
image.png

  1. class Solution {
  2. public:
  3. public int minMeetingRooms(int[][] intervals) {
  4. int intervalsSize = intervals.size();
  5. // 开始开会时间数组,startTimeArr[i] 代表第 i 个会议的开始开会时间
  6. vector<int> startTimeArr(intervalsSize);
  7. // 散会时间数组,endTimeArr[i] 代表第 i 个会议的散会时间
  8. vector<int> endTimeArr(intervalsSize);
  9. for(int i = 0; i < intervalsSize; ++i)
  10. {
  11. startTimeArr[i] = intervals[i][0];
  12. endTimeArr[i] = intervals[i][1];
  13. }
  14. // 分别对开始开会时间数组、散会时间数组排序(从小到大,升序)
  15. sort(startTimeArr.begin(), startTimeArr.end());
  16. sort(endTimerArr.begin(), endTimeArr.end());
  17. // 双指针
  18. int i = 0; // 当前时间已经开始开会的会议个数(包含已经结束的)
  19. int j = 0; // 当前时间已经散会的会议个数
  20. int curMeettingCnt = 0; // 当前时间同时在开会的会议数量,即当前同时使用的会议室数量
  21. int result = 0; // 结果,即每个时间需要会议室数量的最大值
  22. while(i < intervalsSize && j < intervalsSize)
  23. {
  24. // startTimeArr[i] 代表下个开始开会会议的开始时间
  25. // endTimeArr[j] 代表下个散会会议的散会时间
  26. // 取两者中较小值,作为当前跳到的时间
  27. // 跳到下个开始开会会议的开始时间
  28. if(startTimeArr[i] < endTimeArr[j])
  29. {
  30. ++i; // 当前时间已经开始开会的会议个数 +1
  31. ++curMeetingCnt; // 当前时间同时在开会的会议数量 +1
  32. }
  33. // 跳到下个散会会议的散会时间
  34. else
  35. {
  36. ++j; // 当前时间已经散会的会议个数 +1
  37. --curMeetingCnt; // 当前时间同时在开会的会议数量 -1
  38. }
  39. // 将当前使用的会议室数量和全局最大值比较,更新 result
  40. result = max(result, curMeetingCnt);
  41. }
  42. return result;
  43. }
  44. };

复杂度分析:数组 intervals 长为 N,即会议总数为 N

  • 时间复杂度 O(N logN):数组排序
  • 空间复杂度 O(N):

litcode 解答:

  1. /**
  2. * Definition of Interval:
  3. * class Interval {
  4. * public:
  5. * int start, end;
  6. * Interval(int start, int end) {
  7. * this->start = start;
  8. * this->end = end;
  9. * }
  10. * }
  11. */
  12. class Solution {
  13. public:
  14. /**
  15. * @param intervals: an array of meeting time intervals
  16. * @return: the minimum number of conference rooms required
  17. */
  18. int minMeetingRooms(vector<Interval> &intervals) {
  19. int len = intervals.size();
  20. vector<int> startTimes(len); // 开始会议时间数组
  21. vector<int> endTimes(len); // 结束会议时间数组
  22. for(int i = 0; i < len; ++i)
  23. {
  24. startTimes[i] = intervals[i].start;
  25. endTimes[i] = intervals[i].end;
  26. }
  27. // 分别对两个数组进行排序
  28. sort(startTimes.begin(), startTimes.end());
  29. sort(endTimes.begin(), endTimes.end());
  30. int result = 0; // 最多同时开会的会议数量,即最小需要的会议室数量
  31. int cnt = 0; // 当前同时开会的会议数量
  32. // 双指针遍历(每次跳到最近开始会议 or 结束会议的时间)
  33. int startIdx = 0;
  34. int endIdx = 0;
  35. while(startIdx < len)
  36. {
  37. if(startTimes[startIdx] < endTimes[endIdx]) // 开始一个会议
  38. {
  39. ++cnt; // 当前同时开会的会议数量 +1
  40. result = max(result, cnt); // 更新答案
  41. ++startIdx;
  42. }
  43. else // 结束一个会议
  44. {
  45. --cnt; // 当前同时开会的会议数量 -1
  46. ++endIdx;
  47. }
  48. }
  49. return result;
  50. }
  51. };

执行结果:

  1. 执行结果:通过
  2. 执行用时:41 ms, 在所有 C++ 提交中击败了 83.20% 的用户
  3. 内存消耗:2.29 MB, 在所有 C++ 提交中击败了 83.20% 的用户