[LeetCode] 1229. Meeting Scheduler

安排会议日程。题意是给两个人的日程表和一个duration时长,日程表以区间表示,请返回两个人有可能有机会进行一次时长为duration的会议的interval是什么。例子,

Example 1:

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 8
Output: [60,68]

Example 2:

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 12
Output: []

打个比方,比如第一个例子,两人要开一个时长为8分钟的会议,两人的日程如下,结果返回的是60 - 68分钟两人都有时间开会。

这个题不需要考虑一些invalid的case诸如interval的开始时间大于interval的结束时间,所以会好处理一些。思路依然是经典的扫描线。discussion里面目前最高票的答案 [4.4.2020] 给的是priority queue的做法,我没有完全想通。他的思路是去掉两人各自无效的interval(interval本身小于会议时间duration的)之后,把两人所有有效的interval加入pq,pq是按interval的开始时间排序的。先弹出一个interval,比较这个interval的结束时间[1] 是否大于等于堆顶interval[0] + duration。我不理解的地方是他这里是如何保证已经弹出堆顶的元素和目前的堆顶元素不是来自于同一个人。请哪位同学教我一下,非常感谢。

我这里提供一个非pq的做法。先将两个人的intervals按照开始时间排序,之后用双指针分别遍历两个人的intervals,同时找这个可能的interval的start和end分别在哪,如果满足start + duration <= end则记录当前的start和end。如果没有这样的case就返回空的list。

时间O(nlogn) - sort

空间O(1)

Java实现

 1 class Solution {
 2     public List minAvailableDuration(int[][] slots1, int[][] slots2, int duration) {
 3         PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparing(a -> a[0]));
 4         for (int[] s : slots1) {
 5             if (s[1] - s[0] >= duration) {
 6                 pq.offer(s);
 7             }
 8         }
 9         for (int[] s : slots2) {
10             if (s[1] - s[0] >= duration) {
11                 pq.offer(s);
12             }
13         }
14         while (pq.size() > 1) {
15             if (pq.poll()[1] >= pq.peek()[0] + duration) {
16                 return Arrays.asList(pq.peek()[0], pq.peek()[0] + duration);
17             }
18         }
19         return Arrays.asList();
20     }
21 }

 

JavaScript实现

 1 /**
 2  * @param {number[][]} slots1
 3  * @param {number[][]} slots2
 4  * @param {number} duration
 5  * @return {number[]}
 6  */
 7 var minAvailableDuration = function(slots1, slots2, duration) {
 8     slots1.sort((a, b) => a[0] - b[0]);
 9     slots2.sort((a, b) => a[0] - b[0]);
10     let m = slots1.length;
11     let n = slots2.length;
12     let i = 0;
13     let j = 0;
14     while (i < m && j < n) {
15         let start = Math.max(slots1[i][0], slots2[j][0]);
16         let end = Math.min(slots1[i][1], slots2[j][1]);
17         if (start + duration <= end) {
18             return [start, start + duration];
19         } else if (slots1[i][1] < slots2[j][1]) {
20             i++;
21         } else {
22             j++;
23         }
24     }
25     return [];
26 };

 

你可能感兴趣的:([LeetCode] 1229. Meeting Scheduler)