📜  查找与最大片段数重叠的片段

📅  最后修改于: 2021-04-17 18:16:28             🧑  作者: Mango

给定2D数组segment [] [] ,其中每个段的形式均为[L,R]表示(X,Y)坐标,则任务是找到与最大段数重叠的段。

例子:

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

  • 显然,在段[currL,currR]中,其余段的所有“ R”值均小于“ currL” ,而其余段的所有“ L”值均大于“ currR”被算作答案。
  • 将所有“ R”值存储在数组中,并执行二进制搜索以找到所有小于“ currL”“ R”值,并类似地执行此操作以找到所有大于“ currR”“ L”值。
  • 遍历数组,并在每次迭代时以最大交点更新线段坐标。
  • 打印具有最大交点的线段。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the segment which
// overlaps with maximum number of segments
void maxIntersection(int segments[][2], int N)
{
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    vector rvalues(N), lvalues(N);
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i) {
 
        lvalues[i] = segments[i][0];
        rvalues[i] = segments[i][1];
    }
 
    // Co-ordinate compression
    sort(lvalues.begin(), lvalues.end());
    sort(rvalues.begin(), rvalues.end());
 
    // Stores the required segment
    pair answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
 
    for (int i = 0; i < N; ++i) {
 
        // Find number of 'R' coordinates
        // which are less than the 'L'
        // value of the current segment
        int lesser
            = lower_bound(rvalues.begin(), rvalues.end(),
                          segments[i][0])
              - rvalues.begin();
 
        // Find number of 'L' coordinates
        // which are greater than the 'R'
        // value of the current segment
        int greater = max(
            0, N
                   - (int)(upper_bound(lvalues.begin(),
                                       lvalues.end(),
                                       segments[i][1])
                           - lvalues.begin()));
 
        // Segments excluding 'lesser' and
        // 'greater' gives the number of
        // intersections
        if ((N - lesser - greater) >= numIntersections) {
            answer = { segments[i][0], segments[i][1] };
 
            // Update the current maximum
            numIntersections = (N - lesser - greater);
        }
    }
 
    // Print segment coordinates
    cout << answer.first << " " << answer.second;
}
 
// Driver Code
int main()
{
    // Given segments
    int segments[][2] = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = sizeof(segments) / sizeof(segments[0]);
 
    maxIntersection(segments, N);
}


Java
// Java program for the above approach
import java.util.*;
class GFG
{
 
// Function to find the segment which
// overlaps with maximum number of segments
static void maxIntersection(int segments[][], int N)
{
   
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    int []rvalues = new int[N];
    int []lvalues = new int[N];
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i)
    {
 
        lvalues[i] = segments[i][0];
        rvalues[i] = segments[i][1];
    }
 
    // Co-ordinate compression
    Arrays.sort(lvalues);
    Arrays.sort(rvalues);
 
    // Stores the required segment
    int []answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
    for (int i = 0; i < N; ++i)
    {
 
        // Find number of 'R' coordinates
        // which are less than the 'L'
        // value of the current segment
        int lesser
            = lower_bound(rvalues, 0,
                          segments.length,
                          segments[i][0]);
 
        // Find number of 'L' coordinates
        // which are greater than the 'R'
        // value of the current segment
        int greater = Math.max(
            0, N-(upper_bound(lvalues, 0,
                              segments.length,
                              segments[i][1])));
 
        // Segments excluding 'lesser' and
        // 'greater' gives the number of
        // intersections
        if ((N - lesser - greater) >= numIntersections) {
            answer = new int[]{ segments[i][0], segments[i][1] };
 
            // Update the current maximum
            numIntersections = (N - lesser - greater);
        }
    }
 
    // Print segment coordinates
    System.out.print(answer[0]+ " " +  answer[1]);
}
static int lower_bound(int[] a, int low, int high, int element){
    while(low < high){
        int middle = low + (high - low)/2;
        if(element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
 
 
static int upper_bound(int[] a, int low, int high, int element){
    while(low < high){
        int middle = low + (high - low)/2;
        if(a[middle] > element)
            high = middle;
        else
            low = middle + 1;
    }
    return low;
}
// Driver Code
public static void main(String[] args)
{
    // Given segments
    int segments[][] = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = segments.length;
 
    maxIntersection(segments, N);
}
}
// This code is contributed by 29AjayKumar


C#
// C# program for the above approach
using System;
public class GFG
{
 
  // Function to find the segment which
  // overlaps with maximum number of segments
  static void maxIntersection(int [,]segments, int N)
  {
 
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    int []rvalues = new int[N];
    int []lvalues = new int[N];
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i)
    {
      lvalues[i] = segments[i,0];
      rvalues[i] = segments[i,1];
    }
 
    // Co-ordinate compression
    Array.Sort(lvalues);
    Array.Sort(rvalues);
 
    // Stores the required segment
    int []answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
    for (int i = 0; i < N; ++i)
    {
 
      // Find number of 'R' coordinates
      // which are less than the 'L'
      // value of the current segment
      int lesser
        = lower_bound(rvalues, 0,
                      segments.GetLength(0),
                      segments[i,0]);
 
      // Find number of 'L' coordinates
      // which are greater than the 'R'
      // value of the current segment
      int greater = Math.Max(
        0, N-(upper_bound(lvalues, 0,
                          segments.GetLength(0),
                          segments[i,1])));
 
      // Segments excluding 'lesser' and
      // 'greater' gives the number of
      // intersections
      if ((N - lesser - greater) >= numIntersections) {
        answer = new int[]{ segments[i,0], segments[i,1] };
 
        // Update the current maximum
        numIntersections = (N - lesser - greater);
      }
    }
 
    // Print segment coordinates
    Console.Write(answer[0]+ " " +  answer[1]);
  }
  static int lower_bound(int[] a, int low,
                         int high, int element)
  {
    while(low < high)
    {
      int middle = low + (high - low)/2;
      if(element > a[middle])
        low = middle + 1;
      else
        high = middle;
    }
    return low;
  }
 
  static int upper_bound(int[] a, int low,
                         int high, int element)
  {
    while(low < high)
    {
      int middle = low + (high - low)/2;
      if(a[middle] > element)
        high = middle;
      else
        low = middle + 1;
    }
    return low;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
 
    // Given segments
    int [,]segments = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = segments.GetLength(0);
    maxIntersection(segments, N);
  }
}
 
// This code is contributed by shikhasingrajput


输出:
3 6

时间复杂度: O(N * log(N))
辅助空间: O(N)