给定两个数组X[]和Y[] ,代表X和Y数轴上的点,使得每个相似索引的数组元素形成一个线段,即X[i]和Y[i]形成一个线段,任务是找到可以从给定数组中选择的最大线段数。
例子:
Input: X[] = {0, 3, 4, 1, 2}, Y[] = {3, 2, 0, 1, 4}
Output: 3
Explanation: The set of line segments are {{1, 1}, {4, 0}, {0, 3}}.
Input: X[] = {1, 2, 0}, Y[] = {2, 0, 1}
Output: 2
Explanation: The set of line segments is {{1, 2}, {2, 0}}.
方法:这个问题可以通过观察两个线段 (i, j) 之间的交集来解决,只有当X[i] < X[j]和Y[i] > Y[j] 时,反之亦然。因此,可以使用Sorting with Binary search解决问题,使用Sets可以找到这样的线段。
请按照以下步骤解决给定的问题:
- 初始化一个成对向量,比如p来存储对{X[i], Y[i]}作为一个元素。
- 按 X 数轴上点的升序对p对的向量进行排序,因此每条线段i 都满足交点的第一个条件,即X[k] < X[i]其中k < i 。
- 初始化一个 Set,比如s ,以降序存储Y[i]的值。
- 从p的第一个元素,将 Y 坐标(即p[0].second )推入集合中。
- 迭代p 的所有元素,并针对每个元素:
- 执行二分搜索以找到p[i].second 的下界。
- 如果没有获得下界,则意味着p[i].second小于 Set 中存在的所有元素。这满足Y[i] < Y[k]其中k < i的第二个条件,因此将p[i].second推入Set 。
- 如果找到下界,则将其删除并将p[i].second推入 Set 中。
- 最后,返回作为结果的集合的大小。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum number of
// intersecting line segments possible
int solve(int N, int X[], int Y[])
{
// Stores pairs of line
// segments {X[i], Y[i])
vector > p;
for (int i = 0; i < N; i++) {
// Push {X[i], Y[i]} into p
p.push_back({ X[i], Y[i] });
}
// Sort p in ascending order
// of points on X number line
sort(p.begin(), p.end());
// Stores the points on Y number
// line in descending order
set > s;
// Insert the first Y point from p
s.insert(p[0].second);
for (int i = 0; i < N; i++) {
// Binary search to find the
// lower bound of p[i].second
auto it = s.lower_bound(p[i].second);
// If lower_bound doesn't exist
if (it == s.end()) {
// Insert p[i].second into the set
s.insert(p[i].second);
}
else {
// Erase the next lower
//_bound from the set
s.erase(*it);
// Insert p[i].second
// into the set
s.insert(p[i].second);
}
}
// Return the size of the set
// as the final result
return s.size();
}
// Driver Code
int main()
{
// Given Input
int N = 3;
int X[] = { 1, 2, 0 };
int Y[] = { 2, 0, 1 };
// Function call to find the maximum
// number of intersecting line segments
int maxintersection = solve(N, X, Y);
cout << maxintersection;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to find the maximum number of
// intersecting line segments possible
static int solve(int N, int X[], int Y[])
{
// Stores pairs of line
// segments {X[i], Y[i])
ArrayList p = new ArrayList<>();
for(int i = 0; i < N; i++)
{
// Add {X[i], Y[i]} into p
p.add(new int[] { X[i], Y[i] });
}
// Sort p in ascending order
// of points on X number line
Collections.sort(p, (p1, p2) -> {
if (p1[0] != p2[0])
return p1[0] - p2[0];
return p1[1] - p2[1];
});
// Stores the points on Y number
// line in ascending order
TreeSet s = new TreeSet<>();
// Insert the first Y point from p
s.add(p.get(0)[1]);
for(int i = 0; i < N; i++)
{
// Binary search to find the
// floor value of p.get(i)[1]
Integer it = s.floor(p.get(i)[1]);
// If floor value doesn't exist
if (it == null)
{
// Insert p.get(i)[1] into the set
s.add(p.get(i)[1]);
}
else
{
// Erase the next floor
// value from the set
s.remove(it);
// Insert p.get(i)[1]
// into the set
s.add(p.get(i)[1]);
}
}
// Return the size of the set
// as the final result
return s.size();
}
// Driver Code
public static void main(String[] args)
{
// Given Input
int N = 3;
int X[] = { 1, 2, 0 };
int Y[] = { 2, 0, 1 };
// Function call to find the maximum
// number of intersecting line segments
int maxintersection = solve(N, X, Y);
System.out.println(maxintersection);
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
from bisect import bisect_left
# Function to find the maximum number of
# intersecting line segments possible
def solve(N, X, Y):
# Stores pairs of line
# segments {X[i], Y[i])
p = []
for i in range(N):
# Push {X[i], Y[i]} into p
p.append([X[i], Y[i]])
# Sort p in ascending order
# of points on X number line
p = sorted(p)
# Stores the points on Y number
# line in descending order
s = {}
# Insert the first Y pofrom p
s[p[0][1]] = 1
for i in range(N):
# Binary search to find the
# lower bound of p[i][1]
arr = list(s.keys())
it = bisect_left(arr, p[i][1])
# If lower_bound doesn't exist
if (it == len(s)):
# Insert p[i][1] into the set
s[p[i][1]] = 1
else:
# Erase the next lower
# _bound from the set
del s[arr[it]]
# Insert p[i][1]
# into the set
s[p[i][1]] = 1
# Return the size of the set
# as the final result
return len(s)
# Driver Code
if __name__ == '__main__':
# Given Input
N = 3
X = [1, 2, 0]
Y = [2, 0, 1]
# Function call to find the maximum
# number of intersecting line segments
maxintersection = solve(N, X, Y)
print (maxintersection)
# This code is contributed by mohit kumar 29
输出:
2
时间复杂度: O(N log N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。