给定{Start,end}形式的2D数组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 []的大小和存在[]的数组。
辅助空间: O(1)
高效的方法:为了优化上述方法,其思想是使用排序算法和二进制搜索技术。
请按照以下步骤解决问题:
- 以递增的顺序对数组entry []和exist []进行排序。
- 初始化变量ans以存储恰好参加一个会议的最短时间。
- 遍历阵列和用于会议的每个间隔,发现这仅仅是小于或等于使用UPPER_BOUND启动i中的入口[]阵列中,发现这仅仅是大于该值或等于结束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)