给定两个代表区间的二维数组。每个二维数组代表一个区间列表。每个间隔列表是不相交的,并按升序排序。找到两个列表共有的交集或一组范围。
Disjoint means no element is common in a list. Example: {1, 4} and {5, 6} are disjoint while {1, 4} and {2, 5} are not as 2, 3 and 4 are common to both intervals.
例子:
Input: arr1[][] = {{0, 4}, {5, 10}, {13, 20}, {24, 25}}
arr2[][] = {{1, 5}, {8, 12}, {15, 24}, {25, 26}}
Output: {{1, 4}, {5, 5}, {8, 10}, {15, 20}, {24, 24}, {25, 25}}
Explanation:
{1, 4} lies completely within range {0, 4} and {1, 5}. Hence, {1, 4} is the desired intersection. Similarly, {24, 24} lies completely within two intervals {24, 25} and {15, 24}.
Input: arr1[][] = {{0, 2}, {5, 10}, {12, 22}, {24, 25}}
arr2[][] = {{1, 4}, {9, 12}, {15, 24}, {25, 26}}
Output: {{1, 2}, {9, 10}, {12, 12}, {15, 22}, {24, 24}, {25, 25}}
Explanation:
{1, 2} lies completely within range {0, 2} and {1, 4}. Hence, {1, 2} is the desired intersection. Similarly, {12, 12} lies completely within two intervals {12, 22} and {9, 12}.
方法:
为了解决上面提到的问题,可以使用两个指针技术,按照下面给出的步骤:
- 维护两个指针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