• [LeetCode] 1229. Meeting Scheduler


    Given the availability time slots arrays slots1 and slots2 of two people and a meeting duration duration, return the earliest time slot that works for both of them and is of duration duration.

    If there is no common time slot that satisfies the requirements, return an empty array.

    The format of a time slot is an array of two elements [start, end] representing an inclusive time range from start to end.  

    It is guaranteed that no two availability slots of the same person intersect with each other. That is, for any two time slots [start1, end1] and [start2, end2] of the same person, either start1 > end2 or start2 > end1.

    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: []

    Constraints:

    • 1 <= slots1.length, slots2.length <= 10^4
    • slots1[i].length, slots2[i].length == 2
    • slots1[i][0] < slots1[i][1]
    • slots2[i][0] < slots2[i][1]
    • 0 <= slots1[i][j], slots2[i][j] <= 10^9
    • 1 <= duration <= 10^6 

    安排会议日程。

    题意是给两个人的日程表和一个duration时长,日程表以区间表示,请返回两个人有可能有机会进行一次时长为duration的会议的interval是什么。打个比方,比如第一个例子,两人要开一个时长为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。这个思路利用到了题目中给的最后一句话,就是对于同一个人来说,他的duration一定不会互相有交集。那么在从pq弹出的时候,如果有两个intervals能有交集且满足duration,那么说明这两个intervals一定来自不同的人。

    时间O(nlogn) - sort

    空间O(1)

    Java实现 - pq思路

     1 class Solution {
     2     public List<Integer> 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 }

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

    Java实现 - mergesort思路

     1 class Solution {
     2     public List<Integer> minAvailableDuration(int[][] slots1, int[][] slots2, int duration) {
     3         Arrays.sort(slots1, (a, b) -> a[0] - b[0]);
     4         Arrays.sort(slots2, (a, b) -> a[0] - b[0]);
     5         int i = 0;
     6         int j = 0;
     7         int m = slots1.length;
     8         int n = slots2.length;
     9         while (i < m && j < n) {
    10             int intersectionStart = Math.max(slots1[i][0], slots2[j][0]);
    11             int intersectionEnd = Math.min(slots1[i][1], slots2[j][1]);
    12             if (intersectionStart + duration <= intersectionEnd) {
    13                 return Arrays.asList(intersectionStart, intersectionStart + duration);
    14             } else if (slots1[i][1] < slots2[j][1]) {
    15                 i++;
    16             } else {
    17                 j++;
    18             }
    19         }
    20         return new ArrayList<>();
    21     }
    22 }

    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 题目总结

  • 相关阅读:
    uni-app 去除顶部导航栏
    javascript DOM和DOM操作的四种基本方法
    js获取当前时间
    vue自定义事件---拖拽
    富文本去除标签空格
    js贪吃蛇(构造函数)
    vue v-html 富文本解析 空格,换行,图片大小问题
    实验十二 团队项目用户验收评审
    Beta冲刺-第四天
    Beta冲刺-第二天
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12635738.html
Copyright © 2020-2023  润新知