Maximize count of intersecting line segments
Last Updated :
10 Jan, 2023
Given two arrays X[] and Y[], representing points on X and Y number lines, such that every similar-indexed array element forms a line segment, i.e. X[i] and Y[i] forms a line segment, the task is to find the maximum number of line segments that can be selected from the given array.
Examples:
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}}.
Approach: The problem can be solved using the observation that the intersection between two line-segments (i, j) occurs only when X[i] < X[j] and Y[i] > Y[j] or vice-versa. Therefore, the problem can be solved using Sorting along with Binary search, using Sets can be used to find such line segments.
Follow the steps below to solve the given problem:
- Initialize a vector of pairs, say p to store pairs {X[i], Y[i]} as an element.
- Sort the vector of pairs p in ascending order of points on X number line, so every line segment i satisfies the first condition for the intersection i.e X[k] < X[i] where k < i.
- Initialize a Set, say s, to store the values of Y[i] in descending order.
- From the first element from p, push the Y-coordinate (i.e p[0].second) into the set.
- Iterate over all the elements of p, and for each element:
- Perform a binary search to find the lower_bound of p[i].second.
- If there is no lower bound obtained, that means that p[i].second is smaller than all the elements present in the Set. This satisfies the second condition that Y[i] < Y[k] where k < i, so push p[i].second into the Set.
- If a lower bound is found, then remove it and push p[i].second into the Set.
- Finally, return the size of the set that as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve( int N, int X[], int Y[])
{
vector<pair< int , int > > p;
for ( int i = 0; i < N; i++) {
p.push_back({ X[i], Y[i] });
}
sort(p.begin(), p.end());
set< int , greater< int > > s;
s.insert(p[0].second);
for ( int i = 0; i < N; i++) {
auto it = s.lower_bound(p[i].second);
if (it == s.end()) {
s.insert(p[i].second);
}
else {
s.erase(*it);
s.insert(p[i].second);
}
}
return s.size();
}
int main()
{
int N = 3;
int X[] = { 1, 2, 0 };
int Y[] = { 2, 0, 1 };
int maxintersection = solve(N, X, Y);
cout << maxintersection;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static int solve( int N, int X[], int Y[])
{
ArrayList< int []> p = new ArrayList<>();
for ( int i = 0 ; i < N; i++)
{
p.add( new int [] { X[i], Y[i] });
}
Collections.sort(p, (p1, p2) -> {
if (p1[ 0 ] != p2[ 0 ])
return p1[ 0 ] - p2[ 0 ];
return p1[ 1 ] - p2[ 1 ];
});
TreeSet<Integer> s = new TreeSet<>();
s.add(p.get( 0 )[ 1 ]);
for ( int i = 0 ; i < N; i++)
{
Integer it = s.floor(p.get(i)[ 1 ]);
if (it == null )
{
s.add(p.get(i)[ 1 ]);
}
else
{
s.remove(it);
s.add(p.get(i)[ 1 ]);
}
}
return s.size();
}
public static void main(String[] args)
{
int N = 3 ;
int X[] = { 1 , 2 , 0 };
int Y[] = { 2 , 0 , 1 };
int maxintersection = solve(N, X, Y);
System.out.println(maxintersection);
}
}
|
Python3
from bisect import bisect_left
def solve(N, X, Y):
p = []
for i in range (N):
p.append([X[i], Y[i]])
p = sorted (p)
s = {}
s[p[ 0 ][ 1 ]] = 1
for i in range (N):
arr = list (s.keys())
it = bisect_left(arr, p[i][ 1 ])
if (it = = len (s)):
s[p[i][ 1 ]] = 1
else :
del s[arr[it]]
s[p[i][ 1 ]] = 1
return len (s)
if __name__ = = '__main__' :
N = 3
X = [ 1 , 2 , 0 ]
Y = [ 2 , 0 , 1 ]
maxintersection = solve(N, X, Y)
print (maxintersection)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
static int solve( int N, int [] X, int [] Y)
{
var p = new List< int []>();
for ( int i = 0; i < N; i++)
{
p.Add( new int [] { X[i], Y[i] });
}
p.Sort((p1, p2) =>
{
if (p1[0] != p2[0])
return p1[0] - p2[0];
return p1[1] - p2[1];
});
var s = new SortedSet< int >();
s.Add(p[0][1]);
for ( int i = 0; i < N; i++)
{
int it = s.GetViewBetween( int .MinValue, p[i][1]).Max;
if (it == default )
{
s.Add(p[i][1]);
}
else
{
s.Remove(it);
s.Add(p[i][1]);
}
}
return s.Count;
}
static void Main( string [] args)
{
int N = 3;
int [] X = { 1, 2, 0 };
int [] Y = { 2, 0, 1 };
int maxintersection = solve(N, X, Y);
Console.WriteLine(maxintersection);
}
}
|
Javascript
function solve(N, X, Y) {
const p = [];
for (let i = 0; i < N; i++) {
p.push([X[i], Y[i]]);
}
p.sort((a, b) => a[0] - b[0]);
const s = {};
s[p[0][1]] = 1;
for (let i = 0; i < N; i++) {
const arr = Object.keys(s).map((key) => parseInt(key, 10)).sort((a, b) => b - a);
let it = arr.findIndex((elem) => elem <= p[i][1]);
if (it < 0) it = arr.length;
if (it === arr.length) {
s[p[i][1]] = 1;
} else {
delete s[arr[it]];
s[p[i][1]] = 1;
}
}
return Object.keys(s).length;
}
const N = 3;
const X = [1, 2, 0];
const Y = [2, 0, 1];
const maxintersection = solve(N, X, Y);
console.log(maxintersection);
|
Time complexity: O(N log N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...