📜  两个范围之间的交点数

📅  最后修改于: 2021-05-05 01:33:39             🧑  作者: Mango

给定类型1的N范围和类型2的M个范围,任务是找到所有可能的类型1和类型2范围对之间的相交总数。给出了类型1和类型2范围的所有起点和终点。
例子:

方法:

  • 想法是使用包含-排除方法来确定交叉点的总数。
  • 可能的交叉总数为n * m 。现在减去那些与2类范围不相交的类1范围的计数。
  • 那些类型1的范围不会与相交的i2型范围我的开始之前结束2类型范围和开始i的端2类型范围之后。
  • 可以通过使用二进制搜索来确定此计数。 C++内置函数upper_bound可以直接使用。

下面是上述方法的实现:

CPP
// C++ implementation of above approach
#include 
using namespace std;
 
// Function to return total
// number of intersections
int FindIntersection(pair type1[], int n,
                     pair type2[], int m)
{
 
    // Maximum possible number
    // of intersections
    int ans = n * m;
 
    vector start, end;
    for (int i = 0; i < n; i++) {
 
        // Store all starting
        // points of type1 ranges
        start.push_back(type1[i].first);
 
        // Store all endpoints
        // of type1 ranges
        end.push_back(type1[i].second);
    }
 
    sort(start.begin(), start.end());
    sort(end.begin(), end.end());
 
    for (int i = 0; i < m; i++) {
 
        // Starting point of type2 ranges
        int L = type2[i].first;
 
        // Ending point of type2 ranges
        int R = type2[i].second;
 
        // Subtract those ranges which
        // are starting after R
        ans -= (start.end() -
        upper_bound(start.begin(), start.end(), R));
 
        // Subtract those ranges which
        // are ending before L
        ans -=
        (upper_bound(end.begin(), end.end(), L - 1)
        - end.begin());
    }
 
    return ans;
}
 
// Driver Code
int main()
{
 
    pair type1[] =
    { { 1, 2 }, { 2, 3 }, { 4, 5 }, { 6, 7 } };
 
    pair type2[] =
    { { 1, 5 }, { 2, 3 }, { 4, 7 }, { 5, 7 } };
 
    int n = sizeof(type1) / (sizeof(type1[0]));
    int m = sizeof(type2) / sizeof(type2[0]);
 
    cout << FindIntersection(type1, n, type2, m);
 
    return 0;
}


Java
// Java implementation of above approach
import java.io.*;
import java.util.*;
class GFG
{
    static int upperBound(ArrayList a, int low,
                          int high, int element)
    {
    while (low < high)
    {
        int middle = low + (high - low) / 2;
        if (a.get(middle) > element)
        {
            high = middle;
        }
      else
      {
            low = middle + 1;
        }
    }
    return low;
    }
   
    // Function to return total
    // number of intersections
    static int FindIntersection(ArrayList> type1,
                                int n, ArrayList> type2, int m )
    {
       
        // Maximum possible number
        // of intersections
        int ans = n * m;
        ArrayList start = new ArrayList();
        ArrayList end = new ArrayList();
        for (int i = 0; i < n; i++)
        {
           
            // Store all starting
            // points of type1 ranges
            start.add(type1.get(i).get(0));
             
            // Store all endpoints
            // of type1 ranges
            end.add(type1.get(i).get(1));
             
        }
        Collections.sort(start);
        Collections.sort(end);
         
        for (int i = 0; i < m; i++)
        {
           
            // Starting point of type2 ranges
            int L = type2.get(i).get(0);
           
            // Ending point of type2 ranges
            int R = type2.get(i).get(1);
             
            // Subtract those ranges which
            // are starting after R
            ans -= start.size() - upperBound(start, 0, start.size(), R);
             
            // Subtract those ranges which
            // are ending before L
            ans -= upperBound(end, 0, end.size() , L - 1);
             
        }
        return ans;
    }
   
    // Driver Code
    public static void main (String[] args)
    {
        ArrayList> type1 = new ArrayList>();
        type1.add(new ArrayList(Arrays.asList(1,2)));
        type1.add(new ArrayList(Arrays.asList(2,3)));
        type1.add(new ArrayList(Arrays.asList(4,5)));
        type1.add(new ArrayList(Arrays.asList(6,7)));
         
        ArrayList> type2 = new ArrayList>();
        type2.add(new ArrayList(Arrays.asList(1,5)));
        type2.add(new ArrayList(Arrays.asList(2,3)));
        type2.add(new ArrayList(Arrays.asList(4,7)));
        type2.add(new ArrayList(Arrays.asList(5,7)));
         
        int n = type1.size();
        int m = type2.size();
         
        System.out.println(FindIntersection(type1, n, type2, m));
    }
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 implementation of above approach
from bisect import bisect as upper_bound
 
# Function to return total
# number of intersections
def FindIntersection(type1, n, type2, m):
 
    # Maximum possible number
    # of intersections
    ans = n * m
 
    start = []
    end = []
    for i in range(n):
         
        # Store all starting
        # points of type1 ranges
        start.append(type1[i][0])
 
        # Store all endpoints
        # of type1 ranges
        end.append(type1[i][1])
 
    start = sorted(start)
    start = sorted(end)
 
    for i in range(m):
 
        # Starting poof type2 ranges
        L = type2[i][0]
 
        # Ending poof type2 ranges
        R = type2[i][1]
 
        # Subtract those ranges which
        # are starting after R
        ans -= (len(start)- upper_bound(start, R))
 
        # Subtract those ranges which
        # are ending before L
        ans -= (upper_bound(end, L - 1))
 
    return ans
 
# Driver Code
type1 = [ [ 1, 2 ], [ 2, 3 ],
          [ 4, 5 ], [ 6, 7 ] ]
 
type2 = [ [ 1, 5 ], [ 2, 3 ],
          [ 4, 7 ], [ 5, 7 ] ]
 
n = len(type1)
m = len(type2)
 
print(FindIntersection(type1, n, type2, m))
 
# This code is contributed by Mohit Kumar


C#
// C# implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
  static int upperBound(List 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;
  }
 
  // Function to return total
  // number of intersections
  static int FindIntersection(List> type1, int n,
                              List> type2, int m)
  {
 
    // Maximum possible number
    // of intersections
    int ans = n * m;
    List start = new List();
    List end = new List();
    for (int i = 0; i < n; i++)
    {
 
      // Store all starting
      // points of type1 ranges
      start.Add(type1[i][0]);
 
      // Store all endpoints
      // of type1 ranges
      end.Add(type1[i][1]);
    }
    start.Sort();
    end.Sort();
 
    for (int i = 0; i < m; i++)
    {
 
      // Starting point of type2 ranges
      int L = type2[i][0];
 
      // Ending point of type2 ranges
      int R = type2[i][1];
 
      // Subtract those ranges which
      // are starting after R
      ans -= start.Count - upperBound(start, 0, start.Count, R);
 
      // Subtract those ranges which
      // are ending before L
      ans -= upperBound(end, 0, end.Count , L - 1);
    }
    return ans;
  }
 
  // Driver Code
  static public void Main ()
  {
    List> type1 = new List>();
    type1.Add(new List(){1,2});
    type1.Add(new List(){2,3});
    type1.Add(new List(){4,5});
    type1.Add(new List(){6,7});
 
    List> type2 = new List>();
    type2.Add(new List(){1,5});
    type2.Add(new List(){2,3});
    type2.Add(new List(){4,7});
    type2.Add(new List(){5,7});       
    int n = type1.Count;
    int m = type2.Count;
    Console.WriteLine(FindIntersection(type1, n, type2, m));       
  }
}
 
// This code is contributed by rag2127


输出:
9

时间复杂度: O(M * log(N))