间隔表示为开始时间和结束时间的组合。给定一组间隔,请检查是否有两个间隔相交。
例子:
Input: arr[] = {{1, 3}, {5, 7}, {2, 4}, {6, 8}}
Output: true
The intervals {1, 3} and {2, 4} overlap
Input: arr[] = {{1, 3}, {7, 9}, {4, 6}, {10, 13}}
Output: false
No pair of intervals overlap.
预期时间复杂度为O(nLogn),其中n是间隔数。
强烈建议最小化您的浏览器,然后自己尝试。
一个简单的解决方案是考虑每对间隔并检查该对是否相交。该解决方案的时间复杂度为O(n 2 )
方法1
更好的解决方案是使用Sorting 。以下是完整的算法。
1)按照开始时间的升序对所有间隔进行排序。此步骤需要O(nLogn)时间。
2)在排序数组中,如果间隔的开始时间小于上一个间隔的结束时间,则存在重叠。此步骤需要O(n)时间。
因此,该算法的总体时间复杂度为O(nLogn)+ O(n),即O(nLogn)。
以下是上述想法的实现。
C++
// A C++ program to check if any two intervals overlap
#include
#include
using namespace std;
// An interval has start time and end time
struct Interval {
int start;
int end;
};
// Compares two intervals according to their staring time.
// This is needed for sorting the intervals using library
// function std::sort(). See http:// goo.gl/iGspV
bool compareInterval(Interval i1, Interval i2)
{
return (i1.start < i2.start) ? true : false;
}
// Function to check if any two intervals overlap
bool isIntersect(Interval arr[], int n)
{
// Sort intervals in increasing order of start time
sort(arr, arr + n , compareInterval);
// In the sorted array, if start time of an interval
// is less than end of previous interval, then there
// is an overlap
for (int i = 1; i < n; i++)
if (arr[i - 1].end > arr[i].start)
return true;
// If we reach here, then no overlap
return false;
}
// Driver program
int main()
{
Interval arr1[] = { { 1, 3 }, { 7, 9 }, { 4, 6 }, { 10, 13 } };
int n1 = sizeof(arr1) / sizeof(arr1[0]);
isIntersect(arr1, n1) ? cout << "Yes\n" : cout << "No\n";
Interval arr2[] = { { 6, 8 }, { 1, 3 }, { 2, 4 }, { 4, 7 } };
int n2 = sizeof(arr2) / sizeof(arr2[0]);
isIntersect(arr2, n2) ? cout << "Yes\n" : cout << "No\n";
return 0;
}
Java
// A Java program to check if any two intervals overlap
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// An interval has start time and end time
static class Interval
{
int start;
int end;
public Interval(int start, int end)
{
super();
this.start = start;
this.end = end;
}
};
// Function to check if any two intervals overlap
static boolean isIntersect(Interval arr[], int n)
{
// Sort intervals in increasing order of start time
Arrays.sort(arr, (i1, i2) -> {
return i1.start - i2.start;
});
// In the sorted array, if start time of an interval
// is less than end of previous interval, then there
// is an overlap
for(int i = 1; i < n; i++)
if (arr[i - 1].end > arr[i].start)
return true;
// If we reach here, then no overlap
return false;
}
// Driver code
public static void main(String[] args)
{
Interval arr1[] = { new Interval(1, 3),
new Interval(7, 9),
new Interval(4, 6),
new Interval(10, 13) };
int n1 = arr1.length;
if (isIntersect(arr1, n1))
System.out.print("Yes\n");
else
System.out.print("No\n");
Interval arr2[] = { new Interval(6, 8),
new Interval(1, 3),
new Interval(2, 4),
new Interval(4, 7) };
int n2 = arr2.length;
if (isIntersect(arr2, n2))
System.out.print("Yes\n");
else
System.out.print("No\n");
}
}
// This code is contributed by Kingash
C++
// A C++ program to check if any two intervals overlap
#include
#include
using namespace std;
// An interval has start time and end time
struct Interval {
int start;
int end;
};
// Function to check if any two intervals overlap
bool isIntersect(Interval arr[], int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++) {
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int aux[max_ele + 1] = { 0 };
for (int i = 0; i < n; i++) {
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++, aux[y + 1]--;
}
for (int i = 1; i <= max_ele; i++) {
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver program
int main()
{
Interval arr1[] = { { 1, 3 }, { 7, 9 }, { 4, 6 }, { 10, 13 } };
int n1 = sizeof(arr1) / sizeof(arr1[0]);
isIntersect(arr1, n1) ? cout << "Yes\n" : cout << "No\n";
Interval arr2[] = { { 6, 8 }, { 1, 3 }, { 2, 4 }, { 4, 7 } };
int n2 = sizeof(arr2) / sizeof(arr2[0]);
isIntersect(arr2, n2) ? cout << "Yes\n" : cout << "No\n";
return 0;
}
// This Code is written by Anjali Agarwal
Java
// A Java program to check if any two intervals overlap
class GFG
{
// An interval has start time and end time
static class Interval
{
int start;
int end;
public Interval(int start, int end)
{
super();
this.start = start;
this.end = end;
}
};
// Function to check if any two intervals overlap
static boolean isIntersect(Interval arr[], int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int []aux = new int[max_ele + 1];
for (int i = 0; i < n; i++)
{
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for (int i = 1; i <= max_ele; i++)
{
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver program
public static void main(String[] args)
{
Interval arr1[] = { new Interval(1, 3), new Interval(7, 9),
new Interval(4, 6), new Interval(10, 13) };
int n1 = arr1.length;
if(isIntersect(arr1, n1))
System.out.print("Yes\n");
else
System.out.print("No\n");
Interval arr2[] = { new Interval(6, 8), new Interval(1, 3),
new Interval(2, 4), new Interval(4, 7) };
int n2 = arr2.length;
if(isIntersect(arr2, n2))
System.out.print("Yes\n");
else
System.out.print("No\n");
}
}
// This code is contributed by 29AjayKumar
C#
// C# program to check if
// any two intervals overlap
using System;
class GFG
{
// An interval has start time and end time
class Interval
{
public int start;
public int end;
public Interval(int start, int end)
{
this.start = start;
this.end = end;
}
};
// Function to check if
// any two intervals overlap
static bool isIntersect(Interval []arr, int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int []aux = new int[max_ele + 1];
for (int i = 0; i < n; i++)
{
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for (int i = 1; i <= max_ele; i++)
{
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver Code
public static void Main(String[] args)
{
Interval []arr1 = { new Interval(1, 3),
new Interval(7, 9),
new Interval(4, 6),
new Interval(10, 13) };
int n1 = arr1.Length;
if(isIntersect(arr1, n1))
Console.Write("Yes\n");
else
Console.Write("No\n");
Interval []arr2 = { new Interval(6, 8),
new Interval(1, 3),
new Interval(2, 4),
new Interval(4, 7) };
int n2 = arr2.Length;
if(isIntersect(arr2, n2))
Console.Write("Yes\n");
else
Console.Write("No\n");
}
}
// This code is contributed by Rajput-Ji
输出:
No
Yes
方法2 : Anjali Agarwal建议使用此方法。步骤如下:
1. Find the overall maximum element. Let it be max_ele
2. Initialize an array of size max_ele with 0.
3. For every interval [start, end], increment the value at index start, i.e. arr[start]++ and decrement the value at index (end + 1), i.e. arr[end + 1]- -.
4. Compute the prefix sum of this array (arr[]).
5. Every index, i of this prefix sum array will tell how many times i has occurred in all the intervals taken together. If this value is greater than 1, then it occurs in 2 or more intervals.
6. So, simply initialize the result variable as false and while traversing the prefix sum array, change the result variable to true whenever the value at that index is greater than 1.
下面是此(方法2)方法的实现。
C++
// A C++ program to check if any two intervals overlap
#include
#include
using namespace std;
// An interval has start time and end time
struct Interval {
int start;
int end;
};
// Function to check if any two intervals overlap
bool isIntersect(Interval arr[], int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++) {
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int aux[max_ele + 1] = { 0 };
for (int i = 0; i < n; i++) {
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++, aux[y + 1]--;
}
for (int i = 1; i <= max_ele; i++) {
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver program
int main()
{
Interval arr1[] = { { 1, 3 }, { 7, 9 }, { 4, 6 }, { 10, 13 } };
int n1 = sizeof(arr1) / sizeof(arr1[0]);
isIntersect(arr1, n1) ? cout << "Yes\n" : cout << "No\n";
Interval arr2[] = { { 6, 8 }, { 1, 3 }, { 2, 4 }, { 4, 7 } };
int n2 = sizeof(arr2) / sizeof(arr2[0]);
isIntersect(arr2, n2) ? cout << "Yes\n" : cout << "No\n";
return 0;
}
// This Code is written by Anjali Agarwal
Java
// A Java program to check if any two intervals overlap
class GFG
{
// An interval has start time and end time
static class Interval
{
int start;
int end;
public Interval(int start, int end)
{
super();
this.start = start;
this.end = end;
}
};
// Function to check if any two intervals overlap
static boolean isIntersect(Interval arr[], int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int []aux = new int[max_ele + 1];
for (int i = 0; i < n; i++)
{
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for (int i = 1; i <= max_ele; i++)
{
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver program
public static void main(String[] args)
{
Interval arr1[] = { new Interval(1, 3), new Interval(7, 9),
new Interval(4, 6), new Interval(10, 13) };
int n1 = arr1.length;
if(isIntersect(arr1, n1))
System.out.print("Yes\n");
else
System.out.print("No\n");
Interval arr2[] = { new Interval(6, 8), new Interval(1, 3),
new Interval(2, 4), new Interval(4, 7) };
int n2 = arr2.length;
if(isIntersect(arr2, n2))
System.out.print("Yes\n");
else
System.out.print("No\n");
}
}
// This code is contributed by 29AjayKumar
C#
// C# program to check if
// any two intervals overlap
using System;
class GFG
{
// An interval has start time and end time
class Interval
{
public int start;
public int end;
public Interval(int start, int end)
{
this.start = start;
this.end = end;
}
};
// Function to check if
// any two intervals overlap
static bool isIntersect(Interval []arr, int n)
{
int max_ele = 0;
// Find the overall maximum element
for (int i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
// Initialize an array of size max_ele
int []aux = new int[max_ele + 1];
for (int i = 0; i < n; i++)
{
// starting point of the interval
int x = arr[i].start;
// end point of the interval
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for (int i = 1; i <= max_ele; i++)
{
// Calculating the prefix Sum
aux[i] += aux[i - 1];
// Overlap
if (aux[i] > 1)
return true;
}
// If we reach here, then no Overlap
return false;
}
// Driver Code
public static void Main(String[] args)
{
Interval []arr1 = { new Interval(1, 3),
new Interval(7, 9),
new Interval(4, 6),
new Interval(10, 13) };
int n1 = arr1.Length;
if(isIntersect(arr1, n1))
Console.Write("Yes\n");
else
Console.Write("No\n");
Interval []arr2 = { new Interval(6, 8),
new Interval(1, 3),
new Interval(2, 4),
new Interval(4, 7) };
int n2 = arr2.Length;
if(isIntersect(arr2, n2))
Console.Write("Yes\n");
else
Console.Write("No\n");
}
}
// This code is contributed by Rajput-Ji
输出:
No
Yes
时间复杂度: O(max_ele + n)