Skip to content
Related Articles

Related Articles

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 <bits/stdc++.h>
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<pair<int, int> > 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<Integer> 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)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :