给定一个{start, end}形式的二维数组arr[][]代表N 个会议的开始和结束时间,还给定两个数组entry[]和exist[]分别代表会议室的开始和结束时间,任务是找出可以参加会议的最短时间。如果无法参加任何会议,则打印-1 。
例子:
Input: arr[][] = {{15, 19}, {5, 10}, {7, 25}}, entrance[] = {4, 13, 25, 2}, exist[] = {10, 21}
Output: 6
Explanation:
Meeting 1: Enter at the time 13, attend the meeting in the interval (15, 19) and exit at the time 21. Therefore, total time spent in the meeting = 21 – 13 = 8.
Meeting 2: Enter at the time 4, attend the meeting in (5, 10) and exit at the time 10. Therefore, total time spent in the meeting = 10 – 4 = 6.
Meeting 3: Enter at the time 4, attend the meeting in the interval (7, 25). But after the time 25 there is no closing time. Therefore, total time spent is infinite.
Therefore, minimum units of time that can be spent to attend a meeting is 6.
Input: arr[][] = {{1, 2}}, entrance[] = {1, 2}, exist[] = {3, 4}
Output: 2
朴素的方法:解决这个问题最简单的方法是遍历arr[][]并在每个区间{start i , end i }中找到数组中刚好小于或等于arr[i][0]的值入口[] 。此外,在数组exist[] 中找到刚好大于或等于arr[i][1]的值。最后,打印参加一次会议的最短时间。
时间复杂度: O(N*max(P, M)),其中M和P是entry[]和exist[]数组的大小。
辅助空间: O(1)
高效的方法:为了优化上述方法,我们的想法是使用排序算法和二进制搜索技术。
请按照以下步骤解决问题:
- 按升序对数组entry[]和exist[]进行排序。
- 初始化一个变量an来存储参加一次会议的最短时间。
- 遍历数组,对于每个会议间隔,使用upper_bound在entry []数组中找到刚好小于或等于start i的值,并在exist[ ]中找到刚好大于或等于end i的值]数组使用lower_bound。
- 最后,打印参加一次会议的最短时间。
下面是上述方法的实现:
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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live