📜  可以参加的最小会议的长度

📅  最后修改于: 2021-04-22 01:09:52             🧑  作者: Mango

给定{Start,end}形式的2D数组arr [] []代表N次会议的开始和结束时间,还给出了两个数组entry []exist []分别代表会议室的打开和关闭时间,任务是找到可以参加会议的最短时间。如果无法参加任何会议,则打印-1

例子:

天真的方法:解决此问题的最简单方法是遍历arr [] []并针对每个间隔{start i ,end i } ,在数组中找到小于或等于arr [i] [0]的值入口[] 。另外,在数组exist []中找到刚好大于或等于arr [i] [1]的值。最后,打印最短时间参加一次会议。

时间复杂度: O(N * max(P,M)),其中M和P是entry []的大小和存在[]的数组。
辅助空间: O(1)

高效的方法:为了优化上述方法,其思想是使用排序算法和二进制搜索技术。
请按照以下步骤解决问题:

  1. 以递增的顺序对数组entry []exist []进行排序。
  2. 初始化变量ans以存储恰好参加一个会议的最短时间。
  3. 遍历阵列和用于会议的每个间隔,发现这仅仅是小于或等于使用UPPER_BOUND启动i中的入口[]阵列中,发现这仅仅是大于该值或等于结束i。存在[ ]数组使用lower_bound。
  4. 最后,打印最短时间参加一次会议。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to find the minimum time to
// attend exactly one meeting
int minTime(int meeting[][2], int n,
          vector entrance, int m,
             vector &exit, int p)
{
 
    // Stores minimum time to attend
    // exactly one meeting
    int ans = INT_MAX;
 
    // Sort entrance[] array
    sort(entrance.begin(), entrance.end());
 
    // Sort exit[] time
    sort(exit.begin(), exit.end());
 
    // Traverse meeting[][]
    for (int i = 0; i < n; i++) {
         
        // Stores start time of
        // current meeting
        int u = meeting[i][0];
         
        // Stores end time of
        // current meeting
        int v = meeting[i][1];
 
        // Find just greater value of
        // u in entrance[]
        auto it1
          = upper_bound(entrance.begin(),
                     entrance.end(), u);
 
        // Find just greater or equal value
        //  of u in entrance[]
        auto it2
            = lower_bound(exit.begin(),
                         exit.end(), v);
 
        // Stores enter time to attend
        // the current meeting
        int start = it1
              - entrance.begin() - 1;
               
               
        // Stores exist time after
        // attending the meeting   
        int end = it2 - exit.begin();
 
        // Update start lies in range [0, m -1]
        // and end lies in the range [0, p - 1]
        if (start >= 0 && start < m &&
                          end >= 0 && end < p)
                           
            // Update ans             
            ans = min(ans,
                  exit[end] - entrance[start]);
    }
 
    // Return answer
    return ans >= INT_MAX ? -1 : ans;
}
 
// Driver Code
int main()
{
 
    // Stores interval of meeting
    int meeting[][2]
        = { { 15, 19 }, { 5, 10 }, { 7, 25 } };
 
    // Stores entrance timings
    vector entrance = { 4, 13, 25, 2 };
 
    // Stores exit timings
    vector exit = { 10, 25 };
 
    // Stores total count of  meetings
    int n = (sizeof(meeting))
               / sizeof(meeting[0]);
 
    // Stores total entrance timings
    int m = entrance.size();
 
    // Stores total exit timings
    int p = exit.size();
 
    // Minimum time
    cout << minTime(meeting, n, entrance,
                               m, exit, p)
         << endl;
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
   
static Vector exit =
       new Vector<>();
   
// Function to find the
// minimum time to attend
// exactly one meeting
static int minTime(int meeting[][], int n,
                   int[] entrance, int m,
                   int p)
{
  // Stores minimum time to attend
  // exactly one meeting
  int ans = Integer.MAX_VALUE;
 
  // Sort entrance[] array
  Arrays.sort(entrance);
 
  // Sort exit[] time
  Collections.sort(exit);
 
  // Traverse meeting[][]
  for (int i = 0; i < n; i++)
  {
    // Stores start time of
    // current meeting
    int u = meeting[i][0];
 
    // Stores end time of
    // current meeting
    int v = meeting[i][1];
 
    // Find just greater value of
    // u in entrance[]
    int it1 = upper_bound(entrance, 0,
                          entrance.length, u);
 
    // Find just greater or equal
    // value of u in entrance[]
    int it2 = lowerBound(exit, 0,
                         exit.size(), v);
     
    // System.out.println(exit.size());
    // Stores enter time to attend
    // the current meeting
    int start = it1 - 1  ;
 
    // Stores exist time after
    // attending the meeting   
    int end = it2 ;
 
    // Update start lies in range [0, m -1]
    // and end lies in the range [0, p - 1]
    if (start >= 0 && start < m &&
        end >= 0 && end < p)
 
      // Update ans   
      ans = Math.min(ans,
                     exit.get(end) -
                     entrance[start]);
  }
 
  // Return answer
  return ans >= Integer.MAX_VALUE ?
         -1 : ans;
}
 
static int upper_bound(int[] a, int low,
                       int high, int element)
{
  while(low < high)
  {
    int middle = low +
                 (high - low) / 2;
     
    if(a[middle] > element)
      high = middle;
    else
      low = middle + 1;
  }
  return low;
}
 
static int lowerBound(Vector vec,
                      int low, int high,
                      int element)
{
  int [] array =
         new int[vec.size()];
  int k = 0;
   
  for(Integer val : vec)
  {
    array[k] = val;
    k++;
  }
   
  // vec.clear();
  while (low < high)
  {
    int middle = low +
                 (high - low) / 2;
     
    if (element > array[middle])
    {
      low = middle + 1;
    } else
    {
      high = middle;
    }
  }
  return low;
}
 
// Driver Code
public static void main(String[] args)
{
  // Stores interval of meeting
  int meeting[][] = {{15, 19},
                     {5, 10},
                     {7, 25}};
 
  // Stores entrance timings
  int []entrance = {4, 13, 25, 2};
 
  // Stores exit timings
  exit.add(10);
  exit.add(25);
 
  // Stores total count of
  // meetings
  int n = meeting.length;
 
  // Stores total entrance
  // timings
  int m = entrance.length;
 
  // Stores total exit
  // timings
  int p = exit.size();
   
  // Minimum time
  System.out.print(minTime(meeting, n,
                           entrance, m,
                           p) + "\n");
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to implement
# the above approach
from bisect import bisect_left, bisect_right
import sys
 
# Function to find the minimum time to
# attend exactly one meeting
def minTime(meeting, n, entrance, m, exit, p):
     
    # Stores minimum time to attend
    # exactly one meeting
    ans = sys.maxsize
 
    # Sort entrance[] array
    entrance = sorted(entrance)
 
    # Sort exit[] time
    exit = sorted(exit)
     
    # Traverse meeting[][]
    for i in range(n):
         
        # Stores start time of
        # current meeting
        u = meeting[i][0]
         
        # Stores end time of
        # current meeting
        v = meeting[i][1]
 
        # Find just greater value of
        # u in entrance[]
        it1 = bisect_right(entrance, u)
         
        # Find just greater or equal value
        # of u in entrance[]
        it2 = bisect_left(exit, v)
         
        # Stores enter time to attend
        # the current meeting
        start = it1 - 1
         
        # Stores exist time after
        # attending the meeting
        end = it2
         
        # Update start lies in range [0, m -1]
        # and end lies in the range [0, p - 1]
        if (start >= 0 and start < m and
              end >= 0 and end < p):
                   
            # Update ans
            ans = min(ans, exit[end] -
                       entrance[start])
                        
    if ans >= sys.maxsize:
        ans = -1
         
    # Return answer
    return ans
     
# Driver Code
if __name__ == '__main__':
     
    # Stores interval of meeting
    meeting = [ [ 15, 19 ], [ 5, 10 ], [ 7, 25 ] ]
     
    # Stores entrance timings
    entrance = [ 4, 13, 25, 2 ]
     
    # Stores exit timings
    exit = [ 10, 25 ]
     
    # Stores total count of  meetings
    n = len(meeting)
 
    # Stores total entrance timings
    m = len(entrance)
 
    # Stores total exit timings
    p = len(exit)
 
    # Minimum time
    print(minTime(meeting, n, entrance,
                  m, exit, p))
 
# This code is contributed by mohit kumar 29


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
   
static List exit = new List();
   
// Function to find the
// minimum time to attend
// exactly one meeting
static int minTime(int [,]meeting, int n,
                   int[] entrance, int m,
                   int p)
{
   
  // Stores minimum time to attend
  // exactly one meeting
  int ans = int.MaxValue;
 
  // Sort entrance[] array
  Array.Sort(entrance);
 
  // Sort exit[] time
  exit.Sort();
 
  // Traverse meeting[,]
  for(int i = 0; i < n; i++)
  {
     
    // Stores start time of
    // current meeting
    int u = meeting[i, 0];
 
    // Stores end time of
    // current meeting
    int v = meeting[i, 1];
 
    // Find just greater value of
    // u in entrance[]
    int it1 = upper_bound(entrance, 0,
                          entrance.Length, u);
 
    // Find just greater or equal
    // value of u in entrance[]
    int it2 = lowerBound(exit, 0,
                         exit.Count, v);
     
    // Console.WriteLine(exit.Count);
    // Stores enter time to attend
    // the current meeting
    int start = it1 - 1;
 
    // Stores exist time after
    // attending the meeting   
    int end = it2;
 
    // Update start lies in range [0, m -1]
    // and end lies in the range [0, p - 1]
    if (start >= 0 && start < m &&
          end >= 0 && end < p)
 
      // Update ans   
      ans = Math.Min(ans,
                     exit[end] -
                     entrance[start]);
  }
 
  // Return answer
  return ans >= int.MaxValue ?
          -1 : ans;
}
 
static int upper_bound(int[] a, int low,
                       int high, int element)
{
  while (low < high)
  {
    int middle = low + (high - low) / 2;
     
    if (a[middle] > element)
      high = middle;
    else
      low = middle + 1;
  }
  return low;
}
 
static int lowerBound(List vec,
                      int low, int high,
                      int element)
{
  int [] array = new int[vec.Count];
  int k = 0;
   
  foreach(int val in vec)
  {
    array[k] = val;
    k++;
  }
   
  // vec.Clear();
  while (low < high)
  {
    int middle = low + (high - low) / 2;
     
    if (element > array[middle])
    {
      low = middle + 1;
    }
    else
    {
      high = middle;
    }
  }
  return low;
}
 
// Driver Code
public static void Main(String[] args)
{
   
  // Stores interval of meeting
  int [,]meeting = { { 15, 19 },
                     { 5, 10 },
                     { 7, 25 } };
 
  // Stores entrance timings
  int []entrance = { 4, 13, 25, 2 };
   
  // Stores exit timings
  exit.Add(10);
  exit.Add(25);
 
  // Stores total count of
  // meetings
  int n = meeting.GetLength(0);
 
  // Stores total entrance
  // timings
  int m = entrance.Length;
 
  // Stores total exit
  // timings
  int p = exit.Count;
   
  // Minimum time
  Console.Write(minTime(meeting, n,
                        entrance, m,
                        p) + "\n");
}
}
 
// This code is contributed by Rajput-Ji


输出:
6










时间复杂度: O(N * max(logP,logM)),其中M和P是entry []和exist []数组的长度。
辅助空间: O(1)