zoukankan      html  css  js  c++  java
  • [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 题目总结

  • 相关阅读:
    下四国的排长和下四国的小兵 (转载)
    RSS Bandit 不能显示中文界面的解决方法
    Google桌面搜索(GDS)插件的开发工具
    编写VxWorks的Hello World程序
    Visual Studio 2005 Express October 2004 CTP完整版本的下载
    压缩.NET可执行文件的工具
    支持x64的开发工具
    Visual Studio.NET 2002的Service Pack 1发布了
    Windows 嵌入式开发的一些Blog
    利用BITSADMIN获得下载地址
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12635738.html
Copyright © 2011-2022 走看看