📜  查找由两个列表给出的区间的交集

📅  最后修改于: 2021-09-07 03:56:43             🧑  作者: Mango

给定两个代表区间的二维数组。每个二维数组代表一个区间列表。每个间隔列表是不相交的,并按升序排序。找到两个列表共有的交集或一组范围。

例子:

方法:
为了解决上面提到的问题,可以使用两个指针技术,按照下面给出的步骤:

  • 维护两个指针i 和 j 分别遍历两个区间列表 arr1 和 arr2。
  • 现在,如果 arr1[i] 的端点最小,则它只能与 arr2[j] 相交。同样,如果 arr2[j] 的端点最小,则它只能与 arr1[i] 相交。如果发生相交,则找到相交的线段。
  • [l, r] 将是相交线段 iff l <= r,其中l = max(arr1[i][0], arr2[j][0])r = min(arr1[i][1], arr2[j][1])
  • 相应地增加 i 和 j 指针以继续前进。

下面是该方法的实现:

C++
// C++ implementation to find the
// intersection of the two intervals
  
#include 
using namespace std;
  
// Function to print intersecting intervals
void printIntervals(vector > arr1,
                    vector > arr2)
{
  
    // i and j pointers for
    // arr1 and arr2 respectively
    int i = 0, j = 0;
  
    // Size of the two lists
    int n = arr1.size(), m = arr2.size();
  
    // Loop through all intervals unless
    // one of the interval gets exhausted
    while (i < n && j < m) {
        // Left bound for intersecting segment
        int l = max(arr1[i][0], arr2[j][0]);
  
        // Right bound for intersecting segment
        int r = min(arr1[i][1], arr2[j][1]);
  
        // If segment is valid print it
        if (l <= r)
            cout << "{" << l << ", "
                 << r << "}\n";
  
        // If i-th interval's right
        // bound is smaller
        // increment i else
        // increment j
        if (arr1[i][1] < arr2[j][1])
            i++;
        else
            j++;
    }
}
  
// Driver code
int main()
{
  
    vector > arr1
        = { { 0, 4 }, { 5, 10 },
            { 13, 20 }, { 24, 25 } };
  
    vector > arr2
        = { { 1, 5 }, { 8, 12 },
            { 15, 24 }, { 25, 26 } };
  
    printIntervals(arr1, arr2);
  
    return 0;
}


Java
// Java implementation to find 
// intersecting intervals
class GFG{
  
// Function to print intersecting intervals
static void printIntervals(int arr1[][],
                           int arr2[][])
{
      
    // i and j pointers for arr1 and 
    // arr2 respectively
    int i = 0, j = 0;
      
    int n = arr1.length, m = arr2.length;
      
    // Loop through all intervals unless  
    // one of the interval gets exhausted
    while (i < n && j < m) 
    {
          
        // Left bound for intersecting segment
        int l = Math.max(arr1[i][0], arr2[j][0]);
  
        // Right bound for intersecting segment
        int r = Math.min(arr1[i][1], arr2[j][1]);
          
        // If segment is valid print it
        if (l <= r) 
            System.out.println("{" + l + ", " +
                                 r + "}");
  
        // If i-th interval's right bound is 
        // smaller increment i else increment j
        if (arr1[i][1] < arr2[j][1])
            i++;
        else
            j++;
    }
}
  
// Driver code
public static void main(String[] args)
{
    int arr1[][] = { { 0, 4 }, { 5, 10 },
                     { 13, 20 }, { 24, 25 } };
  
    int arr2[][] = { { 1, 5 }, { 8, 12 }, 
                     { 15, 24 }, { 25, 26 } };
  
    printIntervals(arr1, arr2);
}
}
  
// This code is contributed by sarthak_eddy


Python3
# Python3 implementation to find 
# intersecting intervals
  
# Function to print intersecting 
# intervals
def printIntervals(arr1, arr2):
      
    # i and j pointers for arr1 
    # and arr2 respectively
    i = j = 0
      
    n = len(arr1)
    m = len(arr2)
  
    # Loop through all intervals unless one 
    # of the interval gets exhausted
    while i < n and j < m:
          
        # Left bound for intersecting segment
        l = max(arr1[i][0], arr2[j][0])
          
        # Right bound for intersecting segment
        r = min(arr1[i][1], arr2[j][1])
          
        # If segment is valid print it
        if l <= r: 
            print('{', l, ',', r, '}')
  
        # If i-th interval's right bound is 
        # smaller increment i else increment j
        if arr1[i][1] < arr2[j][1]:
            i += 1
        else:
            j += 1
  
# Driver code
arr1 = [ [ 0, 4 ], [ 5, 10 ],
         [ 13, 20 ], [ 24, 25 ] ]
  
arr2 = [ [ 1, 5 ], [ 8, 12 ], 
         [ 15, 24 ], [ 25, 26 ] ]
  
printIntervals(arr1, arr2)
  
# This code is contributed by sarthak_eddy


C#
// C# implementation to find 
// intersecting intervals
using System;
class GFG{
      
// Function to print intersecting intervals
static void printIntervals(int [,]arr1,
                           int [,]arr2)
{
      
    // i and j pointers for arr1 and 
    // arr2 respectively
    int i = 0, j = 0;
      
    int n = arr1.GetLength(0),
        m = arr2.GetLength(0);
      
    // Loop through all intervals unless 
    // one of the interval gets exhausted
    while (i < n && j < m) 
    {
      
        // Left bound for intersecting segment
        int l = Math.Max(arr1[i, 0], arr2[j, 0]);
         
        // Right bound for intersecting segment
        int r = Math.Min(arr1[i, 1], arr2[j, 1]);
      
        // If segment is valid print it
        if (l <= r) 
        Console.WriteLine("{" + l + ", " +
                            r + "}");
                              
        // If i-th interval's right bound is 
        // smaller increment i else increment j
        if (arr1[i, 1] < arr2[j, 1])
            i++;
        else
            j++;
    }
}
  
// Driver code
public static void Main(String[] args)
{
    int [,]arr1 = { { 0, 4 }, { 5, 10 },
                    { 13, 20 }, { 24, 25 } };
                      
    int [,]arr2 = { { 1, 5 }, { 8, 12 }, 
                    { 15, 24 }, { 25, 26 } };
                      
    printIntervals(arr1, arr2);
}
}
  
// This code is contributed by Princi Singh


输出:
{1, 4}
{5, 5}
{8, 10}
{15, 20}
{24, 24}
{25, 25}

时间复杂度: O(N + M) ,其中 N 和 M 是二维数组的长度

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live