# Maximize count of intersecting line segments

• Difficulty Level : Medium
• Last Updated : 26 Mar, 2021

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:

1. Initialize a vector of pairs, say p to store pairs {X[i], Y[i]} as an element.
2. 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.
3. Initialize a Set, say s, to store the values of Y[i] in descending order.
4. From the first element from p, push the Y-coordinate (i.e p[0].second) into the set.
5. 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.
6. Finally, return the size of the set that as the result.

Below is the implementation of the above approach:

## 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<``int``, greater<``int``> > 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<``int``[]> 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`
Output:
`2`

Time complexity: O(N log N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up