Consider a big party where a log register for guest’s entry and exit times is maintained. Find the time at which there are maximum guests in the party. Note that entries in register are not in any order.
Example :
Input: arrl[] = {1, 2, 9, 5, 5}
exit[] = {4, 5, 12, 9, 12}
First guest in array arrives at 1 and leaves at 4,
second guest arrives at 2 and leaves at 5, and so on.
Output: 5
There are maximum 3 guests at time 5.
Below is a Simple Method to solve this problem.
1) Traverse all intervals and find min and max time (time at which first guest arrives and time at which last guest leaves)
2) Create a count array of size ‘max – min + 1’. Let the array be count[].
3) For each interval [x, y], run a loop for i = x to y and do following in loop.
count[i – min]++;
4) Find the index of maximum element in count array. Let this index be ‘max_index’, return max_index + min.
Above solution requires O(max-min+1) extra space. Also time complexity of above solution depends on lengths of intervals. In worst case, if all intervals are from ‘min’ to ‘max’, then time complexity becomes O((max-min+1)*n) where n is number of intervals.
An Efficient Solution is to use sorting n O(nLogn) time. The idea is to consider all events (all arrivals and exits) in sorted order. Once we have all events in sorted order, we can trace the number of guests at any time keeping track of guests that have arrived, but not exited.
Consider the above example.
arr[] = {1, 2, 10, 5, 5}
dep[] = {4, 5, 12, 9, 12}
Below are all events sorted by time. Note that in sorting, if two
events have same time, then arrival is preferred over exit.
Time Event Type Total Number of Guests Present
------------------------------------------------------------
1 Arrival 1
2 Arrival 2
4 Exit 1
5 Arrival 2
5 Arrival 3 // Max Guests
5 Exit 2
9 Exit 1
10 Arrival 2
12 Exit 1
12 Exit 0
Total number of guests at any time can be obtained by subtracting
total exits from total arrivals by that time.
So maximum guests are three at time 5.
Following is the implementation of above approach. Note that the implementation doesn’t create a single sorted list of all events, rather it individually sorts arr[] and dep[] arrays, and then uses merge process of merge sort to process them together as a single sorted array.
C++
#include<iostream>
#include<algorithm>
using namespace std;
void findMaxGuests( int arrl[], int exit [], int n)
{
sort(arrl, arrl+n);
sort( exit , exit +n);
int guests_in = 1, max_guests = 1, time = arrl[0];
int i = 1, j = 0;
while (i < n && j < n)
{
if (arrl[i] <= exit [j])
{
guests_in++;
if (guests_in > max_guests)
{
max_guests = guests_in;
time = arrl[i];
}
i++;
}
else
{
guests_in--;
j++;
}
}
cout << "Maximum Number of Guests = " << max_guests
<< " at time " << time ;
}
int main()
{
int arrl[] = {1, 2, 10, 5, 5};
int exit [] = {4, 5, 12, 9, 12};
int n = sizeof (arrl)/ sizeof (arrl[0]);
findMaxGuests(arrl, exit , n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void findMaxGuests( int arrl[], int exit[],
int n)
{
Arrays.sort(arrl);
Arrays.sort(exit);
int guests_in = 1 , max_guests = 1 , time = arrl[ 0 ];
int i = 1 , j = 0 ;
while (i < n && j < n)
{
if (arrl[i] <= exit[j])
{
guests_in++;
if (guests_in > max_guests)
{
max_guests = guests_in;
time = arrl[i];
}
i++;
}
else
{
guests_in--;
j++;
}
}
System.out.println( "Maximum Number of Guests = " +
max_guests + " at time " + time);
}
public static void main(String[] args)
{
int arrl[] = { 1 , 2 , 10 , 5 , 5 };
int exit[] = { 4 , 5 , 12 , 9 , 12 };
int n = arrl.length;
findMaxGuests(arrl, exit, n);
}
}
|
Python3
def findMaxGuests(arrl, exit, n):
arrl.sort();
exit.sort();
guests_in = 1 ;
max_guests = 1 ;
time = arrl[ 0 ];
i = 1 ;
j = 0 ;
while (i < n and j < n):
if (arrl[i] < = exit[j]):
guests_in = guests_in + 1 ;
if (guests_in > max_guests):
max_guests = guests_in;
time = arrl[i];
i = i + 1 ;
else :
guests_in = guests_in - 1 ;
j = j + 1 ;
print ( "Maximum Number of Guests =" ,
max_guests, "at time" , time)
arrl = [ 1 , 2 , 10 , 5 , 5 ];
exit = [ 4 , 5 , 12 , 9 , 12 ];
n = len (arrl);
findMaxGuests(arrl, exit, n);
|
C#
using System;
class GFG
{
static void findMaxGuests( int []arrl,
int []exit,
int n)
{
Array.Sort(arrl);
Array.Sort(exit);
int guests_in = 1,
max_guests = 1,
time = arrl[0];
int i = 1, j = 0;
while (i < n && j < n)
{
if (arrl[i] <= exit[j])
{
guests_in++;
if (guests_in > max_guests)
{
max_guests = guests_in;
time = arrl[i];
}
i++;
}
else
{
guests_in--;
j++;
}
}
Console.Write( "Maximum Number of Guests = " +
max_guests +
" at time " + time);
}
public static void Main()
{
int []arrl = {1, 2, 10, 5, 5};
int []exit = {4, 5, 12, 9, 12};
int n = arrl.Length;
findMaxGuests(arrl, exit, n);
}
}
|
PHP
<?php
function findMaxGuests( $arrl , $exit , $n )
{
sort( $arrl );
sort( $exit );
$guests_in = 1;
$max_guests = 1;
$time = $arrl [0];
$i = 1;
$j = 0;
while ( $i < $n and $j < $n )
{
if ( $arrl [ $i ] <= $exit [ $j ])
{
$guests_in ++;
if ( $guests_in > $max_guests )
{
$max_guests = $guests_in ;
$time = $arrl [ $i ];
}
$i ++;
}
else
{
$guests_in --;
$j ++;
}
}
echo "Maximum Number of Guests = " , $max_guests
, " at time " , $time ;
}
$arr1 = array (1, 2, 10, 5, 5);
$exit = array (4, 5, 12, 9, 120);
$n = count ( $arr1 );
findMaxGuests( $arr1 , $exit , $n );
?>
|
Javascript
<script>
function findMaxGuests(arrl, exit, n)
{
arrl.sort( function (a, b){ return a - b});
exit.sort( function (a, b){ return a - b});
let guests_in = 1, max_guests = 1, time = arrl[0];
let i = 1, j = 0;
while (i < n && j < n)
{
if (arrl[i] <= exit[j])
{
guests_in++;
if (guests_in > max_guests)
{
max_guests = guests_in;
time = arrl[i];
}
i++;
}
else
{
guests_in--;
j++;
}
}
document.write( "Maximum Number of Guests =
" + max_guests + " at time " + time);
}
let arrl = [1, 2, 10, 5, 5];
let exit = [4, 5, 12, 9, 12];
let n = arrl.length;
findMaxGuests(arrl, exit, n);
</script>
|
Output :
Maximum Number of Guests = 3 at time 5
Time Complexity: O(nLogn).
Auxiliary Space: O(1) as no extra space has been taken.
Another Efficient Solution :
1). Create an auxiliary array used for storing dynamic data of starting and ending points.
2). Loop through the whole array of elements and increase the value at the starting point by 1 and similarly decrease the value after ending point by 1.
[Here we use the expressions “x[start[i]]+=1” and “x[end[i]+1]-=1”]
3). While looping, after calculating the auxiliary array: permanently add the value at current index and check for the maximum valued index traversing from left to right.
C++
#include<bits/stdc++.h>
using namespace std;
void maxOverlap(vector< int >& start, vector< int >& end )
{
int n= start.size();
int maxa=*max_element(start.begin(), start.end());
int maxb=*max_element(end.begin(), end.end());
int maxc = max(maxa, maxb);
int x[maxc + 2];
memset (x, 0, sizeof x);
int cur = 0, idx;
for ( int i = 0; i < n; i++)
{
++x[start[i]];
--x[end[i]+1];
}
int maxy = INT_MIN;
for ( int i = 0; i <= maxc; i++)
{
cur += x[i];
if (maxy < cur)
{
maxy = cur;
idx = i;
}
}
cout<< "Maximum value is " <<maxy<< " at position " <<idx<<endl;
}
int main()
{
vector< int > start = {13, 28, 29, 14, 40, 17, 3},
end = {107, 95, 111, 105, 70, 127, 74};
maxOverlap(start,end);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
class GFG
{
public static void maxOverlap( int []start, int [] end , int n)
{
int maxa = Arrays.stream(start).max().getAsInt();
int maxb = Arrays.stream(end).max().getAsInt();
int maxc = Math.max(maxa,maxb);
int []x = new int [maxc + 2 ];
Arrays.fill(x, 0 );
int cur= 0 ,idx= 0 ;
for ( int i = 0 ; i < n; i++)
{
++x[start[i]];
--x[end[i]+ 1 ];
}
int maxy=Integer.MIN_VALUE;
for ( int i = 0 ; i <= maxc; i++)
{
cur+=x[i];
if (maxy < cur)
{
maxy = cur;
idx = i;
}
}
System.out.println( "Maximum value is:" +
maxy+ " at position: " +idx+ "" );
}
public static void main(String[] args)
{
int [] start = new int []{ 13 , 28 , 29 , 14 , 40 , 17 , 3 };
int [] end = new int []{ 107 , 95 , 111 , 105 , 70 , 127 , 74 };
int n = start.length;
maxOverlap(start,end,n);
}
}
|
Python3
import sys
def maxOverlap(start,end):
n = len (start)
maxa = max (start)
maxb = max (end)
maxc = max (maxa,maxb)
x = (maxc + 2 ) * [ 0 ]
cur = 0 ; idx = 0
for i in range ( 0 ,n) :
x[start[i]] + = 1
x[end[i] + 1 ] - = 1
maxy = - 1
for i in range ( 0 ,maxc + 1 ):
cur + = x[i]
if maxy<cur :
maxy = cur
idx = i
print ( "Maximum value is: {0:d}" . format (maxy),
" at position: {0:d}" . format (idx))
if __name__ = = "__main__" :
start = [ 13 , 28 , 29 , 14 , 40 , 17 , 3 ]
end = [ 107 , 95 , 111 , 105 , 70 , 127 , 74 ]
maxOverlap(start,end)
|
C#
using System;
using System.Linq;
class GFG
{
public static void maxOverlap( int []start, int [] end , int n)
{
int maxa = start.Max();
int maxb = end.Max();
int maxc = Math.Max(maxa,maxb);
int [] x = new int [maxc + 2];
int cur = 0,idx = 0;
for ( int i = 0; i < n; i++)
{
++x[start[i]];
--x[end[i]+1];
}
int maxy= int .MinValue;
for ( int i = 0; i <= maxc; i++)
{
cur+=x[i];
if (maxy < cur)
{
maxy = cur;
idx = i;
}
}
Console.WriteLine( "Maximum value is " +
maxy+ " at position: " +idx+ "" );
}
public static void Main()
{
int []start = {13, 28, 29, 14, 40, 17, 3 };
int []end = {107, 95, 111, 105, 70, 127, 74};
int n = start.Length;
maxOverlap(start,end,n);
}
}
|
PHP
<?php
function maxOverlap( $start , $end )
{
$n = count ( $start );
$maxa = max( $start );
$maxb = max( $end );
$maxc = max( $maxa , $maxb );
$x = array_fill (0, $maxc + 2, 0);
$cur = 0;
for ( $i = 0; $i < $n ; $i ++)
{
++ $x [ $start [ $i ]];
-- $x [ $end [ $i ]+1];
}
$maxy =-PHP_INT_MAX;
for ( $i = 0; $i <= $maxc ; $i ++)
{
$cur += $x [ $i ];
if ( $maxy < $cur )
{
$maxy = $cur ;
$idx = $i ;
}
}
echo "Maximum value is " . $maxy . " at position " . $idx . "\n" ;
}
$start = array (13,28,29,14,40,17,3);
$end = array (107,95,111,105,70,127,74);
maxOverlap( $start , $end );
?>
|
Javascript
<script>
function maxOverlap(start, end, n)
{
let maxa = 0;
for (let i = 0; i < start.length; i++)
{
maxa = Math.max(maxa, start[i]);
}
let maxb = 0;
for (let i = 0; i < end.length; i++)
{
maxb = Math.max(maxb, end[i]);
}
let maxc = Math.max(maxa,maxb);
let x = new Array(maxc + 2);
x.fill(0);
let cur = 0,idx = 0;
for (let i = 0; i < n; i++)
{
++x[start[i]];
--x[end[i]+1];
}
let maxy = Number.MIN_VALUE;
for (let i = 0; i <= maxc; i++)
{
cur+=x[i];
if (maxy < cur)
{
maxy = cur;
idx = i;
}
}
document.write(
"Maximum value is " + maxy+ " at position: " +idx+ ""
);
}
let start = [13, 28, 29, 14, 40, 17, 3 ];
let end = [107, 95, 111, 105, 70, 127, 74];
let n = start.length;
maxOverlap(start,end,n);
</script>
|
OutputMaximum value is 7 at position 40