给定一个由N对{L, R}类型组成的数组arr[] ,每对代表X轴上的一个段,任务是找到一个段与其他段的最大交叉点数。
例子:
Input: arr[] = {{1, 6}, {5, 5}, {2, 3}}
Output: 2
Explanation:
Below are the count of each segment that overlaps with the other segments:
- The first segment [1, 6] intersects with 2 segments [5, 5] and [2, 3].
- The second segment [5, 5] intersects with 1 segment [1, 6].
- The third segment [2, 3] intersects with 1 segment [1, 6].
Therefore, the maximum number of intersections among all the segment is 2.
Input: arr[][] = {{4, 8}, {3, 6}, {7, 11}, {9, 10}}
Output: 2
朴素的方法:解决给定问题的最简单的方法是迭代所有段,并通过与所有其他段检查它来为每个段计算交叉点的数量,然后打印获得的所有交叉点计数中的最大值。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:上述方法也可以基于以下观察进行优化:
- 可以通过遍历每个段并使用二分搜索计算不与当前段相交的段数并从中找到与当前段相交的段数来优化上述方法
- 假设[L, R]是当前段,而[P, Q]是另一个段,那么如果Q < L或P > R ,则段[L, R]不与段[P, Q]相交。
- 假设X是不与段[L, R]相交的段数,那么与段[L, R]相交的段数= (N – 1 – X) 。
请按照以下步骤解决问题:
- 将段的所有左侧点存储在数组中,例如L[] ,将数组中段的所有右侧点存储在R[] 中。
- 按升序对数组L[]和R[]进行排序。
- 初始化一个变量,比如count为0来存储一个段的最大交叉点的计数。
- 遍历数组arr[]并执行以下步骤:
- 使用 lower_bound() 计算当前段{arr[i][0], arr[i][1]}剩下的段数,并将其存储在变量中,例如cnt 。
- 使用 upper_bound() 计算当前段{arr[i][0], arr[i][1]}右边的段数,并通过它增加cnt的计数。
- 将count的值更新为count和(N – cnt – 1)的最大值。
- 完成上述步骤后,打印计数的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum number
// of intersections one segment has with
// all the other given segments
int maximumIntersections(int arr[][2],
int N)
{
// Stores the resultant maximum count
int count = 0;
// Stores the starting and the
// ending points
int L[N], R[N];
for (int i = 0; i < N; i++) {
L[i] = arr[i][0];
R[i] = arr[i][1];
}
// Sort arrays points in the
// ascending order
sort(L, L + N);
sort(R, R + N);
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
int l = arr[i][0];
int r = arr[i][1];
// Find the count of segments
// on left of ith segment
int x = lower_bound(R, R + N, l) - R;
// Find the count of segments
// on right of ith segment
int y = N - (upper_bound(L, L + N, r) - L);
// Find the total segments not
// intersecting with the current
// segement
int cnt = x + y;
// Store the count of segments
// that intersect with the
// ith segment
cnt = N - cnt - 1;
// Update the value of count
count = max(count, cnt);
}
// Return the resultant count
return count;
}
// Driver Code
int main()
{
int arr[][2] = { { 1, 6 }, { 5, 5 }, { 2, 3 } };
int N = sizeof(arr) / sizeof(arr[0]);
cout << maximumIntersections(arr, N);
return 0;
}
Java
// java program for the above approach
import java.util.*;
class GFG
{static int lower_bound(int[] a, int low, int high, long element)
{
while(low < high)
{
int middle = low + (high - low) / 2;
if(element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
static int maximumIntersections(int [][]arr,
int N)
{
// Stores the resultant maximum count
int count = 0;
// Stores the starting and the
// ending points
int[] L = new int[N];
int[] R = new int[N];
for (int i = 0; i < N; i++) {
L[i] = arr[i][0];
R[i] = arr[i][1];
}
// Sort arrays points in the
// ascending order
Arrays.sort(L);
Arrays.sort(R);
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
int l = arr[i][0];
int r = arr[i][1];
// Find the count of segments
// on left of ith segment
int x = lower_bound(L, 0,N, l);
// Find the count of segments
// on right of ith segment
int y = N-lower_bound(R, 0,N, r+1);
// Find the total segments not
// intersecting with the current
// segement
int cnt = x + y;
// Store the count of segments
// that intersect with the
// ith segment
cnt = N - cnt - 1;
// Update the value of count
count = Math.max(count, cnt);
}
// Return the resultant count
return count;
}
// Driver Code
public static void main(String[] args)
{
int arr[][] = { { 1, 6 }, { 5, 5 }, { 2, 3 } };
int N = arr.length;
System.out.println(maximumIntersections(arr, N));
}
}
// This code is contributed by stream_cipher.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
static int lower_bound(int[] a, int low,
int high, long element)
{
while(low < high)
{
int middle = low + (high - low) / 2;
if (element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
static int maximumIntersections(int [,]arr,
int N)
{
// Stores the resultant maximum count
int count = 0;
// Stores the starting and the
// ending points
int[] L = new int[N];
int[] R = new int[N];
for(int i = 0; i < N; i++)
{
L[i] = arr[i, 0];
R[i] = arr[i, 1];
}
// Sort arrays points in the
// ascending order
Array.Sort(L);
Array.Sort(R);
// Traverse the array arr[]
for(int i = 0; i < N; i++)
{
int l = arr[i, 0];
int r = arr[i, 1];
// Find the count of segments
// on left of ith segment
int x = lower_bound(L, 0, N, l);
// Find the count of segments
// on right of ith segment
int y = N-lower_bound(R, 0, N, r + 1);
// Find the total segments not
// intersecting with the current
// segement
int cnt = x + y;
// Store the count of segments
// that intersect with the
// ith segment
cnt = N - cnt - 1;
// Update the value of count
count = Math.Max(count, cnt);
}
// Return the resultant count
return count;
}
// Driver Code
public static void Main()
{
int [,]arr = new int[3, 2]{ { 1, 6 },
{ 5, 5 },
{ 2, 3 } };
int N = 3;
Console.Write(maximumIntersections(arr, N));
}
}
// This code is contributed by SURENDRA_GANGWAR
Javascript
输出:
2
时间复杂度: O(N*log N)
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live