Given n appointments, find all conflicting appointments
Last Updated :
28 Mar, 2023
Given n appointments, find all conflicting appointments.
Examples:
Input: appointments[] = { {1, 5} {3, 7}, {2, 6}, {10, 15}, {5, 6}, {4, 100}}
Output: Following are conflicting intervals
[3,7] Conflicts with [1,5]
[2,6] Conflicts with [1,5]
[5,6] Conflicts with [3,7]
[4,100] Conflicts with [1,5]
An appointment is conflicting if it conflicts with any of the previous appointments in the array.
The Easy Way To Go Forward With: The Approach:
Kind of brute force we traverse over backside of current index and check for overlapping.
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
int main()
{
vector<vector< int > > v{
{ 1, 5 }, { 3, 7 }, { 2, 6 },
{ 10, 15 }, { 5, 6 }, { 4, 100 }
};
int n = v.size();
vector<pair<pair< int , int >, pair< int , int > > > result;
for ( int i = 0; i < n; i++) {
for ( int j = i - 1; j >= 0; j--) {
if (v[j][0] < v[i][1]) {
result.push_back({ { v[i][0], v[i][1] },
{ v[j][1], v[j][0] } });
}
}
}
for ( auto it : result) {
cout << "[" << it.first.first << ","
<< it.first.second
<< "] having Conflict with [" ;
cout << it.second.first << "," << it.second.second
<< "]" << endl;
}
return 0;
}
|
Java
import java.util.*;
public class Main {
static class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
public static void main(String[] args) {
List<List<Integer>> v = new ArrayList<>();
v.add(Arrays.asList( 1 , 5 ));
v.add(Arrays.asList( 3 , 7 ));
v.add(Arrays.asList( 2 , 6 ));
v.add(Arrays.asList( 10 , 15 ));
v.add(Arrays.asList( 5 , 6 ));
v.add(Arrays.asList( 4 , 100 ));
int n = v.size();
List<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> result = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
for ( int j = i - 1 ; j >= 0 ; j--) {
if (v.get(j).get( 0 ) < v.get(i).get( 1 )) {
result.add( new Pair<>(
new Pair<>(v.get(i).get( 0 ), v.get(i).get( 1 )),
new Pair<>(v.get(j).get( 1 ), v.get(j).get( 0 ))
));
}
}
}
for (Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> it : result) {
System.out.printf( "[%d,%d] having Conflict with [%d,%d]\n" ,
it.getKey().getKey(), it.getKey().getValue(),
it.getValue().getKey(), it.getValue().getValue());
}
}
}
|
Python3
v = [[ 1 , 5 ], [ 3 , 7 ], [ 2 , 6 ], [ 10 , 15 ],
[ 5 , 6 ], [ 4 , 100 ]]
n = len (v)
result = []
for i in range (n):
for j in range (i - 1 , - 1 , - 1 ):
if v[j][ 0 ] < v[i][ 1 ]:
result.append([[v[i][ 0 ], v[i][ 1 ]], [v[j][ 1 ], v[j][ 0 ]]])
for it in result:
print ( "[" + str (it[ 0 ][ 0 ]) + "," + str (it[ 0 ][ 1 ]) +
"] having Conflict with [" + str (it[ 1 ][ 0 ]) + "," + str (it[ 1 ][ 1 ]) + "]" )
|
C#
using System;
using System.Collections.Generic;
class Program {
static void Main( string [] args)
{
List<List< int > > v = new List<List< int > >() {
new List< int >{ 1, 5 }, new List< int >{ 3, 7 },
new List< int >{ 2, 6 },
new List< int >{ 10, 15 },
new List< int >{ 5, 6 }, new List< int >
{
4, 100
}
};
int n = v.Count;
List<Tuple<Tuple< int , int >, Tuple< int , int > > >
result = new List<Tuple<Tuple< int , int >,
Tuple< int , int > > >();
for ( int i = 0; i < n; i++) {
for ( int j = i - 1; j >= 0; j--) {
if (v[j][0] < v[i][1]) {
result.Add(Tuple.Create(
Tuple.Create(v[i][0], v[i][1]),
Tuple.Create(v[j][1], v[j][0])));
}
}
}
foreach ( var it in result)
{
Console.Write(
"[{0},{1}] having Conflict with [{2},{3}]\n" ,
it.Item1.Item1, it.Item1.Item2,
it.Item2.Item1, it.Item2.Item2);
}
}
}
|
Javascript
const v = [[1, 5], [3, 7], [2, 6], [10, 15], [5, 6], [4, 100]];
const n = v.length;
const result = [];
for (let i = 0; i < n; i++)
{
for (let j = i - 1; j >= 0; j--)
{
if (v[j][0] < v[i][1]) {
result.push([
[v[i][0], v[i][1]],[v[j][1], v[j][0]]]);
}
}
}
for (let it of result) {
console.log( "[" + it[0][0] + "," + it[0][1] +
"] having Conflict with [" + it[1][0] + "," +
it[1][1] + "]" );
}
|
Output
[3,7] having Conflict with [5,1]
[2,6] having Conflict with [7,3]
[2,6] having Conflict with [5,1]
[10,15] having Conflict with [6,2]
[10,15] having Conflict with [7,3]
[10,15] having Conflict with [5,1]
[5,6] having Conflict with [6,2]
[5,6] having Conflict with [7,3]
[5,6] having Conflict with [5,1]
[4,100] having Conflict with [6,5]
[4,100] having Conflict with [15,10]
[4,100] having Conflict with [6,2]
[4,100] having Conflict with [7,3]
[4,100] having Conflict with [5,1]
Complexity Analysis:
Time Complexity: O(n^2).
Auxiliary Space: O(n)+O(n),in the worst case.
We strongly recommend to minimize the browser and try this yourself first.
A Simple Solution is to one by one process all appointments from the second appointment to last. For every appointment i, check if it conflicts with i-1, i-2, … 0. The time complexity of this method is O(n2).
We can use Interval Tree to solve this problem in O(nLogn) time. Following is a detailed algorithm.
- Create an Interval Tree, initially with the first appointment.
- Do following for all other appointments starting from the second one.
- Check if the current appointment conflicts with any of the existing appointments in Interval Tree. If conflicts, then print the current appointment. This step can be done O(Logn) time.
- Insert the current appointment in Interval Tree. This step also can be done O(Logn) time.
Following is the implementation of the above idea.
C++
#include <bits/stdc++.h>
using namespace std;
struct Interval
{
int low, high;
};
struct ITNode
{
Interval *i;
int max;
ITNode *left, *right;
};
ITNode * newNode(Interval i)
{
ITNode *temp = new ITNode;
temp->i = new Interval(i);
temp->max = i.high;
temp->left = temp->right = NULL;
return temp;
};
ITNode *insert(ITNode *root, Interval i)
{
if (root == NULL)
return newNode(i);
int l = root->i->low;
if (i.low < l)
root->left = insert(root->left, i);
else
root->right = insert(root->right, i);
if (root->max < i.high)
root->max = i.high;
return root;
}
bool doOVerlap(Interval i1, Interval i2)
{
if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
}
Interval *overlapSearch(ITNode *root, Interval i)
{
if (root == NULL) return NULL;
if (doOVerlap(*(root->i), i))
return root->i;
if (root->left != NULL && root->left->max >= i.low)
return overlapSearch(root->left, i);
return overlapSearch(root->right, i);
}
void printConflicting(Interval appt[], int n)
{
ITNode *root = NULL;
root = insert(root, appt[0]);
for ( int i=1; i<n; i++)
{
Interval *res = overlapSearch(root, appt[i]);
if (res != NULL)
cout << "[" << appt[i].low << "," << appt[i].high
<< "] Conflicts with [" << res->low << ","
<< res->high << "]\n" ;
root = insert(root, appt[i]);
}
}
int main()
{
Interval appt[] = { {1, 5}, {3, 7}, {2, 6}, {10, 15},
{5, 6}, {4, 100}};
int n = sizeof (appt)/ sizeof (appt[0]);
cout << "Following are conflicting intervals\n" ;
printConflicting(appt, n);
return 0;
}
|
Java
class GfG{
static class Interval
{
int low, high;
}
static class ITNode
{
Interval i;
int max;
ITNode left, right;
}
static Interval newNode( int l, int h)
{
Interval temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
}
static ITNode newNode(Interval i)
{
ITNode temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
}
static ITNode insert(ITNode root, Interval i)
{
if (root == null )
return newNode(i);
int l = root.i.low;
if (i.low < l)
root.left = insert(root.left, i);
else
root.right = insert(root.right, i);
if (root.max < i.high)
root.max = i.high;
return root;
}
static boolean doOVerlap(Interval i1, Interval i2)
{
if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
}
static Interval overlapSearch(ITNode root,
Interval i)
{
if (root == null )
return null ;
if (doOVerlap(root.i, i))
return root.i;
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
return overlapSearch(root.right, i);
}
static void printConflicting(Interval appt[], int n)
{
ITNode root = null ;
root = insert(root, appt[ 0 ]);
for ( int i = 1 ; i < n; i++)
{
Interval res = overlapSearch(root, appt[i]);
if (res != null )
System.out.print( "[" + appt[i].low +
"," + appt[i].high +
"] Conflicts with [" +
res.low + "," +
res.high + "]\n" );
root = insert(root, appt[i]);
}
}
public static void main(String[] args)
{
Interval appt[] = new Interval[ 6 ];
appt[ 0 ] = newNode( 1 , 5 );
appt[ 1 ] = newNode( 3 , 7 );
appt[ 2 ] = newNode( 2 , 6 );
appt[ 3 ] = newNode( 10 , 15 );
appt[ 4 ] = newNode( 5 , 6 );
appt[ 5 ] = newNode( 4 , 100 );
int n = appt.length;
System.out.print(
"Following are conflicting intervals\n" );
printConflicting(appt, n);
}
}
|
Python3
class Interval:
def __init__( self ):
self .low = None
self .high = None
class ITNode:
def __init__( self ):
self . max = None
self .i = None
self .left = None
self .right = None
def newNode(j):
temp = ITNode()
temp.i = j
temp. max = j[ 1 ]
return temp
def doOVerlap(i1, i2):
if (i1[ 0 ] < i2[ 1 ] and i2[ 0 ] < i1[ 1 ]):
return True
return False
def insert(node, data):
global succ
root = node
if (node = = None ):
return newNode(data)
if (data[ 0 ] < node.i[ 0 ]):
root.left = insert(node.left, data)
else :
root.right = insert(node.right, data)
if root. max < data[ 1 ]:
root. max = data[ 1 ]
return root
def overlapSearch(root, i):
if (root = = None ):
return None
if (doOVerlap(root.i, i)):
return root.i
if (root.left ! = None and root.left. max > = i[ 0 ]):
return overlapSearch(root.left, i)
return overlapSearch(root.right, i)
def printConflicting(appt, n):
root = None
root = insert(root, appt[ 0 ])
for i in range ( 1 , n):
res = overlapSearch(root, appt[i])
if (res ! = None ):
print ( "[" , appt[i][ 0 ], "," , appt[i][ 1 ],
"] Conflicts with [" , res[ 0 ],
"," , res[ 1 ], "]" )
root = insert(root, appt[i])
if __name__ = = '__main__' :
appt = [ [ 1 , 5 ], [ 3 , 7 ],
[ 2 , 6 ], [ 10 , 15 ],
[ 5 , 6 ], [ 4 , 100 ] ]
n = len (appt)
print ( "Following are conflicting intervals" )
printConflicting(appt, n)
|
C#
using System;
public class GfG
{
public
class Interval
{
public
int low, high;
}
public
class ITNode
{
public
Interval i;
public
int max;
public
ITNode left, right;
}
static Interval newNode( int l, int h)
{
Interval temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
}
static ITNode newNode(Interval i)
{
ITNode temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
}
static ITNode insert(ITNode root, Interval i)
{
if (root == null )
return newNode(i);
int l = root.i.low;
if (i.low < l)
root.left = insert(root.left, i);
else
root.right = insert(root.right, i);
if (root.max < i.high)
root.max = i.high;
return root;
}
static bool doOVerlap(Interval i1, Interval i2)
{
if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
}
static Interval overlapSearch(ITNode root,
Interval i)
{
if (root == null )
return null ;
if (doOVerlap(root.i, i))
return root.i;
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
return overlapSearch(root.right, i);
}
static void printConflicting(Interval []appt, int n)
{
ITNode root = null ;
root = insert(root, appt[0]);
for ( int i = 1; i < n; i++)
{
Interval res = overlapSearch(root, appt[i]);
if (res != null )
Console.Write( "[" + appt[i].low +
"," + appt[i].high +
"] Conflicts with [" +
res.low + "," +
res.high + "]\n" );
root = insert(root, appt[i]);
}
}
public static void Main(String[] args)
{
Interval []appt = new Interval[6];
appt[0] = newNode(1, 5);
appt[1] = newNode(3, 7);
appt[2] = newNode(2, 6);
appt[3] = newNode(10, 15);
appt[4] = newNode(5, 6);
appt[5] = newNode(4, 100);
int n = appt.Length;
Console.Write(
"Following are conflicting intervals\n" );
printConflicting(appt, n);
}
}
|
Javascript
<script>
class Interval
{
constructor()
{
this .low = 0;
this .high = 0;
}
}
class ITNode
{
constructor()
{
this .max = 0;
this .left = null ;
this .right = null ;
this .i = null ;
}
}
function newNodeDouble(l, h)
{
var temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
}
function newNodeSingle(i)
{
var temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
}
function insert(root, i)
{
if (root == null )
return newNodeSingle(i);
var l = root.i.low;
if (i.low < l)
root.left = insert(root.left, i);
else
root.right = insert(root.right, i);
if (root.max < i.high)
root.max = i.high;
return root;
}
function doOVerlap(i1, i2)
{
if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
}
function overlapSearch(root, i)
{
if (root == null )
return null ;
if (doOVerlap(root.i, i))
return root.i;
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
return overlapSearch(root.right, i);
}
function printConflicting(appt, n)
{
var root = null ;
root = insert(root, appt[0]);
for ( var i = 1; i < n; i++)
{
var res = overlapSearch(root, appt[i]);
if (res != null )
document.write( "[" + appt[i].low +
"," + appt[i].high +
"] Conflicts with [" +
res.low + "," +
res.high + "]<br>" );
root = insert(root, appt[i]);
}
}
var appt = Array(6);
appt[0] = newNodeDouble(1, 5);
appt[1] = newNodeDouble(3, 7);
appt[2] = newNodeDouble(2, 6);
appt[3] = newNodeDouble(10, 15);
appt[4] = newNodeDouble(5, 6);
appt[5] = newNodeDouble(4, 100);
var n = appt.length;
document.write(
"Following are conflicting intervals<br>" );
printConflicting(appt, n);
</script>
|
Output
Following are conflicting intervals
[3,7] Conflicts with [1,5]
[2,6] Conflicts with [1,5]
[5,6] Conflicts with [3,7]
[4,100] Conflicts with [1,5]
Note that the above implementation uses a simple Binary Search Tree insert operations. Therefore, the time complexity of the above implementation is more than O(nLogn). We can use Red-Black Tree or AVL Tree balancing techniques to make the above implementation O(nLogn).
Auxiliary Space: O(h), Here h is the height of the tree. The extra space is used due to recursion call stack.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...