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.
#include <bits/stdc++.h> #include <iostream> using namespace std;
int main()
{ // Given Appointments.
vector<vector< int > > v{
{ 1, 5 }, { 3, 7 }, { 2, 6 },
{ 10, 15 }, { 5, 6 }, { 4, 100 }
};
// sort according to start time of meet/appointment.
// sort(v.begin(), v.end());
// number of pair or appointments.
int n = v.size();
// for stoping the overlapping
// vector<bool>vis(n,0);
// traverse over and check for it.
vector<pair<pair< int , int >, pair< int , int > > > result;
for ( int i = 0; i < n; i++) {
for ( int j = i - 1; j >= 0; j--) {
// to reduce extra/unwanted comparisons.
// if(v[j][0]>v[i][1])break;
// else{
if (v[j][0] < v[i][1]) {
result.push_back({ { v[i][0], v[i][1] },
{ v[j][1], v[j][0] } });
}
// }
}
}
// final output.
for ( auto it : result) {
cout << "[" << it.first.first << ","
<< it.first.second
<< "] having Conflict with [" ;
cout << it.second.first << "," << it.second.second
<< "]" << endl;
}
// code by Sanket Gode.
return 0;
} |
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) {
// Given Appointments.
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 ));
// sort according to start time of meet/appointment.
// sort(v.begin(), v.end());
// number of pair or appointments.
int n = v.size();
// for stoping the overlapping
// vector<bool>vis(n,0);
// traverse over and check for it.
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--) {
// to reduce extra/unwanted comparisons.
// if(v[j][0]>v[i][1])break;
// else{
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 ))
));
}
}
}
// final output.
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());
}
}
} |
v = [[ 1 , 5 ], [ 3 , 7 ], [ 2 , 6 ], [ 10 , 15 ],
[ 5 , 6 ], [ 4 , 100 ]]
# sort according to start time of meet/appointment. # v.sort() # number of pair or appointments. n = len (v)
# for stoping the overlapping #vis = [0]*n # traverse over and check for it. result = []
for i in range (n):
for j in range (i - 1 , - 1 , - 1 ):
# to reduce extra/unwanted comparisons.
# if(v[j][0]>v[i][1]):
# break
# else:
if v[j][ 0 ] < v[i][ 1 ]:
result.append([[v[i][ 0 ], v[i][ 1 ]], [v[j][ 1 ], v[j][ 0 ]]])
# final output. for it in result:
print ( "[" + str (it[ 0 ][ 0 ]) + "," + str (it[ 0 ][ 1 ]) +
"] having Conflict with [" + str (it[ 1 ][ 0 ]) + "," + str (it[ 1 ][ 1 ]) + "]" )
|
using System;
using System.Collections.Generic;
class Program {
static void Main( string [] args)
{
// Given Appointments.
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
}
};
// sort according to start time of meet/appointment.
// v.Sort();
// number of pair or appointments.
int n = v.Count;
// for stopping the overlapping
// List<bool> vis = new List<bool>(n);
// for (int i = 0; i < n; i++) vis.Add(false);
// traverse over and check for it.
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--) {
// to reduce extra/unwanted comparisons.
// if(v[j][0]>v[i][1])break;
// else{
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])));
}
// }
}
}
// final output.
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);
}
}
} |
// equivalent JavaScript code const v = [[1, 5], [3, 7], [2, 6], [10, 15], [5, 6], [4, 100]]; // sort according to start time of meet/appointment. // v.sort() const n = v.length; // number of pair or appointments.
const result = []; for (let i = 0; i < n; i++)
{ for (let j = i - 1; j >= 0; j--)
{ // to reduce extra/unwanted comparisons. // if(v[j][0]>v[i][1]){ // break; // } // else{ if (v[j][0] < v[i][1]) {
result.push([ [v[i][0], v[i][1]],[v[j][1], v[j][0]]]); } } } // final output. for (let it of result) {
console.log( "[" + it[0][0] + "," + it[0][1] +
"] having Conflict with [" + it[1][0] + "," +
it[1][1] + "]" );
} |
[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++ program to print all conflicting appointments in a // given set of appointments #include <bits/stdc++.h> using namespace std;
// Structure to represent an interval struct Interval
{ int low, high;
}; // Structure to represent a node in Interval Search Tree struct ITNode
{ Interval *i; // 'i' could also be a normal variable
int max;
ITNode *left, *right;
}; // A utility function to create a new Interval Search Tree Node ITNode * newNode(Interval i) { ITNode *temp = new ITNode;
temp->i = new Interval(i);
temp->max = i.high;
temp->left = temp->right = NULL;
return temp;
}; // A utility function to insert a new Interval Search Tree // Node. This is similar to BST Insert. Here the low value // of interval is used tomaintain BST property ITNode *insert(ITNode *root, Interval i) { // Base case: Tree is empty, new node becomes root
if (root == NULL)
return newNode(i);
// Get low value of interval at root
int l = root->i->low;
// If root's low value is smaller, then new interval
// goes to left subtree
if (i.low < l)
root->left = insert(root->left, i);
// Else, new node goes to right subtree.
else
root->right = insert(root->right, i);
// Update the max value of this ancestor if needed
if (root->max < i.high)
root->max = i.high;
return root;
} // A utility function to check if given two intervals overlap bool doOVerlap(Interval i1, Interval i2)
{ if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
} // The main function that searches a given interval i // in a given Interval Tree. Interval *overlapSearch(ITNode *root, Interval i) { // Base Case, tree is empty
if (root == NULL) return NULL;
// If given interval overlaps with root
if (doOVerlap(*(root->i), i))
return root->i;
// If left child of root is present and max of left child
// is greater than or equal to given interval, then i may
// overlap with an interval is left subtree
if (root->left != NULL && root->left->max >= i.low)
return overlapSearch(root->left, i);
// Else interval can only overlap with right subtree
return overlapSearch(root->right, i);
} // This function prints all conflicting appointments in a given // array of appointments. void printConflicting(Interval appt[], int n)
{ // Create an empty Interval Search Tree, add first
// appointment
ITNode *root = NULL;
root = insert(root, appt[0]);
// Process rest of the intervals
for ( int i=1; i<n; i++)
{
// If current appointment conflicts with any of the
// existing intervals, print it
Interval *res = overlapSearch(root, appt[i]);
if (res != NULL)
cout << "[" << appt[i].low << "," << appt[i].high
<< "] Conflicts with [" << res->low << ","
<< res->high << "]\n" ;
// Insert this appointment
root = insert(root, appt[i]);
}
} // Driver program to test above functions int main()
{ // Let us create interval tree shown in above figure
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 program to print all conflicting // appointments in a given set of appointments class GfG{
// Structure to represent an interval static class Interval
{ int low, high;
} static class ITNode
{ // 'i' could also be a normal variable
Interval i;
int max;
ITNode left, right;
} // A utility function to create a new node static Interval newNode( int l, int h)
{ Interval temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
} // A utility function to create a new node static ITNode newNode(Interval i)
{ ITNode temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
} // A utility function to insert a new // Interval Search Tree Node. This is // similar to BST Insert. Here the // low value of interval is used to // maintain BST property static ITNode insert(ITNode root, Interval i)
{ // Base case: Tree is empty,
// new node becomes root
if (root == null )
return newNode(i);
// Get low value of interval at root
int l = root.i.low;
// If root's low value is smaller,
// then new interval goes to left subtree
if (i.low < l)
root.left = insert(root.left, i);
// Else, new node goes to right subtree.
else
root.right = insert(root.right, i);
// Update the max value of this
// ancestor if needed
if (root.max < i.high)
root.max = i.high;
return root;
} // A utility function to check if given // two intervals overlap static boolean doOVerlap(Interval i1, Interval i2)
{ if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
} // The main function that searches a given // interval i in a given Interval Tree. static Interval overlapSearch(ITNode root,
Interval i)
{ // Base Case, tree is empty
if (root == null )
return null ;
// If given interval overlaps with root
if (doOVerlap(root.i, i))
return root.i;
// If left child of root is present
// and max of left child is greater
// than or equal to given interval,
// then i may overlap with an interval
// is left subtree
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
// Else interval can only
// overlap with right subtree
return overlapSearch(root.right, i);
} // This function prints all conflicting // appointments in a given array of appointments. static void printConflicting(Interval appt[], int n)
{ // Create an empty Interval Search
// Tree, add first appointment
ITNode root = null ;
root = insert(root, appt[ 0 ]);
// Process rest of the intervals
for ( int i = 1 ; i < n; i++)
{
// If current appointment conflicts
// with any of the existing intervals,
// print it
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" );
// Insert this appointment
root = insert(root, appt[i]);
}
} // Driver code 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);
} } // This code is contributed by tushar_bansal |
# Python3 program to print all conflicting # appointments in a given set of appointments # Structure to represent an interval class Interval:
def __init__( self ):
self .low = None
self .high = None
# Structure to represent a node # in Interval Search Tree class ITNode:
def __init__( self ):
self . max = None
self .i = None
self .left = None
self .right = None
def newNode(j):
#print(j)
temp = ITNode()
temp.i = j
temp. max = j[ 1 ]
return temp
# A utility function to check if # given two intervals overlap def doOVerlap(i1, i2):
if (i1[ 0 ] < i2[ 1 ] and i2[ 0 ] < i1[ 1 ]):
return True
return False
# Function to create a new node def insert(node, data):
global succ
# If the tree is empty, return a new node
root = node
if (node = = None ):
return newNode(data)
# If key is smaller than root's key, go to left
# subtree and set successor as current node
# print(node)
if (data[ 0 ] < node.i[ 0 ]):
# print(node)
root.left = insert(node.left, data)
# Go to right subtree
else :
root.right = insert(node.right, data)
if root. max < data[ 1 ]:
root. max = data[ 1 ]
return root
# The main function that searches a given # interval i in a given Interval Tree. def overlapSearch(root, i):
# Base Case, tree is empty
if (root = = None ):
return None
# If given interval overlaps with root
if (doOVerlap(root.i, i)):
return root.i
# If left child of root is present and
# max of left child is greater than or
# equal to given interval, then i may
# overlap with an interval is left subtree
if (root.left ! = None and root.left. max > = i[ 0 ]):
return overlapSearch(root.left, i)
# Else interval can only overlap
# with right subtree
return overlapSearch(root.right, i)
# This function prints all conflicting # appointments in a given array of # appointments. def printConflicting(appt, n):
# Create an empty Interval Search Tree,
# add first appointment
root = None
root = insert(root, appt[ 0 ])
# Process rest of the intervals
for i in range ( 1 , n):
# If current appointment conflicts
# with any of the existing intervals,
# print it
res = overlapSearch(root, appt[i])
if (res ! = None ):
print ( "[" , appt[i][ 0 ], "," , appt[i][ 1 ],
"] Conflicts with [" , res[ 0 ],
"," , res[ 1 ], "]" )
# Insert this appointment
root = insert(root, appt[i])
# Driver code if __name__ = = '__main__' :
# Let us create interval tree
# shown in above figure
appt = [ [ 1 , 5 ], [ 3 , 7 ],
[ 2 , 6 ], [ 10 , 15 ],
[ 5 , 6 ], [ 4 , 100 ] ]
n = len (appt)
print ( "Following are conflicting intervals" )
printConflicting(appt, n)
# This code is contributed by mohit kumar 29 |
// C# program to print all conflicting // appointments in a given set of appointments using System;
public class GfG
{ // Structure to represent an interval public class Interval
{ public
int low, high;
} public class ITNode
{ // 'i' could also be a normal variable
public
Interval i;
public
int max;
public
ITNode left, right; } // A utility function to create a new node static Interval newNode( int l, int h)
{ Interval temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
} // A utility function to create a new node static ITNode newNode(Interval i)
{ ITNode temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
} // A utility function to insert a new // Interval Search Tree Node. This is // similar to BST Insert. Here the // low value of interval is used to // maintain BST property static ITNode insert(ITNode root, Interval i)
{ // Base case: Tree is empty,
// new node becomes root
if (root == null )
return newNode(i);
// Get low value of interval at root
int l = root.i.low;
// If root's low value is smaller,
// then new interval goes to left subtree
if (i.low < l)
root.left = insert(root.left, i);
// Else, new node goes to right subtree.
else
root.right = insert(root.right, i);
// Update the max value of this
// ancestor if needed
if (root.max < i.high)
root.max = i.high;
return root;
} // A utility function to check if given // two intervals overlap static bool doOVerlap(Interval i1, Interval i2)
{ if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
} // The main function that searches a given // interval i in a given Interval Tree. static Interval overlapSearch(ITNode root,
Interval i)
{ // Base Case, tree is empty
if (root == null )
return null ;
// If given interval overlaps with root
if (doOVerlap(root.i, i))
return root.i;
// If left child of root is present
// and max of left child is greater
// than or equal to given interval,
// then i may overlap with an interval
// is left subtree
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
// Else interval can only
// overlap with right subtree
return overlapSearch(root.right, i);
} // This function prints all conflicting // appointments in a given array of appointments. static void printConflicting(Interval []appt, int n)
{ // Create an empty Interval Search
// Tree, add first appointment
ITNode root = null ;
root = insert(root, appt[0]);
// Process rest of the intervals
for ( int i = 1; i < n; i++)
{
// If current appointment conflicts
// with any of the existing intervals,
// print it
Interval res = overlapSearch(root, appt[i]);
if (res != null )
Console.Write( "[" + appt[i].low +
"," + appt[i].high +
"] Conflicts with [" +
res.low + "," +
res.high + "]\n" );
// Insert this appointment
root = insert(root, appt[i]);
}
} // Driver code 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);
} } // This code is contributed by gauravrajput1 |
<script> // Javascript program to print all conflicting // appointments in a given set of appointments // Structure to represent an interval class Interval { constructor()
{
this .low = 0;
this .high = 0;
}
} class ITNode { // 'i' could also be a normal variable
constructor()
{
this .max = 0;
this .left = null ;
this .right = null ;
this .i = null ;
}
} // A utility function to create a new node function newNodeDouble(l, h)
{ var temp = new Interval();
temp.low = l;
temp.high = h;
return temp;
} // A utility function to create a new node function newNodeSingle(i)
{ var temp = new ITNode();
temp.i = i;
temp.max = i.high;
temp.left = temp.right = null ;
return temp;
} // A utility function to insert a new // Interval Search Tree Node. This is // similar to BST Insert. Here the // low value of interval is used to // maintain BST property function insert(root, i)
{ // Base case: Tree is empty,
// new node becomes root
if (root == null )
return newNodeSingle(i);
// Get low value of interval at root
var l = root.i.low;
// If root's low value is smaller,
// then new interval goes to left subtree
if (i.low < l)
root.left = insert(root.left, i);
// Else, new node goes to right subtree.
else
root.right = insert(root.right, i);
// Update the max value of this
// ancestor if needed
if (root.max < i.high)
root.max = i.high;
return root;
} // A utility function to check if given // two intervals overlap function doOVerlap(i1, i2)
{ if (i1.low < i2.high && i2.low < i1.high)
return true ;
return false ;
} // The main function that searches a given // interval i in a given Interval Tree. function overlapSearch(root, i)
{ // Base Case, tree is empty
if (root == null )
return null ;
// If given interval overlaps with root
if (doOVerlap(root.i, i))
return root.i;
// If left child of root is present
// and max of left child is greater
// than or equal to given interval,
// then i may overlap with an interval
// is left subtree
if (root.left != null &&
root.left.max >= i.low)
return overlapSearch(root.left, i);
// Else interval can only
// overlap with right subtree
return overlapSearch(root.right, i);
} // This function prints all conflicting // appointments in a given array of appointments. function printConflicting(appt, n)
{ // Create an empty Interval Search
// Tree, add first appointment
var root = null ;
root = insert(root, appt[0]);
// Process rest of the intervals
for ( var i = 1; i < n; i++)
{
// If current appointment conflicts
// with any of the existing intervals,
// print it
var res = overlapSearch(root, appt[i]);
if (res != null )
document.write( "[" + appt[i].low +
"," + appt[i].high +
"] Conflicts with [" +
res.low + "," +
res.high + "]<br>" );
// Insert this appointment
root = insert(root, appt[i]);
}
} // Driver code 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> |
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.