📜  检查给定间隔中是否有两个间隔相交

📅  最后修改于: 2021-04-30 02:40:16             🧑  作者: Mango

间隔表示为开始时间和结束时间的组合。给定一组间隔,请检查是否有两个间隔相交。

例子:

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

方法2Anjali Agarwal建议使用此方法。步骤如下:

下面是此(方法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)