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

  • 相关阅读:
    Rsync常见运维操作命令
    [图文详解] Sublime Text在Windows/Ubuntu/Mac OSX中配置使用CTags
    Sublime Text : 创建工程
    Sublime Text 插件 & 使用技巧
    如何解决adb devices 端口被占用的问题zz
    Nginx 服务器安装及配置文件详解
    把notepad++设置为系统全局文本默认打开应用
    Ubuntu 下载 & 编译 Android5.1 源码
    同步、更新、下载Android Source & SDK from 国内镜像站
    如何为Linux生成和打上patch
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12635738.html
Copyright © 2020-2023  润新知