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

📅  最后修改于: 2021-04-29 18:50:33             🧑  作者: Mango

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

例子:

方法:
为了解决上述问题,可以按照以下步骤使用两种指针技术:

  • 保持两个指针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是二维数组的长度