📌  相关文章
📜  N 个给定段中的任何一个可能的最大交叉点数

📅  最后修改于: 2021-10-27 03:24:18             🧑  作者: Mango

给定一个由N{L, R}类型组成的数组arr[] ,每对代表X轴上的一个段,任务是找到一个段与其他段的最大交叉点数。

例子:

朴素的方法:解决给定问题的最简单的方法是迭代所有段,并通过与所有其他段检查它来为每个段计算交叉点的数量,然后打印获得的所有交叉点计数中的最大值。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效的方法:上述方法也可以基于以下观察进行优化:

  • 可以通过遍历每个段并使用二分搜索计算不与当前段相交的段数并从中找到与当前段相交的段数来优化上述方法
  • 假设[L, R]是当前段,而[P, Q]是另一个段,那么如果Q < LP > R ,则段[L, R]不与段[P, Q]相交。
  • 假设X是不与段[L, R]相交的段数,那么与段[L, R]相交的段数= (N – 1 – X)

请按照以下步骤解决问题:

  • 将段的所有左侧点存储在数组中,例如L[] ,将数组中段的所有右侧点存储在R[] 中
  • 按升序对数组L[]R[]进行排序。
  • 初始化一个变量,比如count0来存储一个段的最大交叉点的计数。
  • 遍历数组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
        // segment
        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
        // segment
        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.


Python3
# Python 3 program for the above approach
from bisect import bisect_left, bisect_right
 
 
def lower_bound(a, low, high, element):
 
    while(low < high):
 
        middle = low + (high - low) // 2
        if(element > a[middle]):
            low = middle + 1
        else:
            high = middle
 
    return low
 
 
# Function to find the maximum number
# of intersections one segment has with
# all the other given segments
def maximumIntersections(arr,
                         N):
 
    # Stores the resultant maximum count
    count = 0
 
    # Stores the starting and the
    # ending points
    L = [0]*N
    R = [0]*N
 
    for i in range(N):
        L[i] = arr[i][0]
        R[i] = arr[i][1]
 
    # Sort arrays points in the
    # ascending order
    L.sort()
    R.sort()
 
    # Traverse the array arr[]
    for i in range(N):
        l = arr[i][0]
        r = arr[i][1]
 
        # Find the count of segments
        # on left of ith segment
        x = lower_bound(L, 0, N, l)
 
        # Find the count of segments
        # on right of ith segment
        y = N-lower_bound(R, 0, N, r+1)
 
        # Find the total segments not
        # intersecting with the current
        # segment
        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
if __name__ == "__main__":
 
    arr = [[1, 6], [5, 5], [2, 3]]
    N = len(arr)
    print(maximumIntersections(arr, N))
 
    # This code is contributed by ukasp.


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
        // segment
        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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程