给定类型1的N个范围和类型2的M个范围,任务是找到所有可能的类型1和类型2范围对之间的相交总数。给出了类型1和类型2范围的所有起点和终点。
例子:
Input : N = 2, M = 2
type1[ ] = { { 1, 3 }, { 5, 9 } }
type2[ ] = { { 2, 8 }, { 9, 12 } }
Output : 3
Range {2, 8} intersects with type1 ranges {1, 3} and {5, 9}
Range {9, 12} intersects with {5, 9} only.
So the total number of intersections is 3.
Input : N = 3, M = 1
type1[ ] = { { 1, 8 }, { 5, 10 }, { 14, 28 }
type2[ ] = { { 2, 8 } }
Output : 2
方法:
- 想法是使用包含-排除方法来确定交叉点的总数。
- 可能的交叉总数为n * m 。现在减去那些与第2类范围不相交的类1范围的计数。
- 那些类型1的范围不会与相交的第i个2型范围我的开始之前结束第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))