Maximum intersection of a horizontal lines with a vertical
Last Updated :
27 Mar, 2025
Given n horizontal line segments are arranged on the X-axis of a 2D plane. The start and end point of each line segment is given in an nx2 matrix lines[ ][ ], the task is to find the maximum number of intersections possible of any vertical line with the given n line segments.
Examples:
Input: n = 4, lines[][] = [ [ 1, 3 ], [ 2, 3], [ 1, 2 ], [ 4, 4 ] ]
Output: 3
Explanation: A vertical line at X = 2 passes through {1, 3}, {2, 3}, {1, 2}, i.e. three of the given horizontal lines.
Input: n= 3, lines[][] = [ [ 1, 3 ], [ 5, 6 ], [ 3, 4 ] ]
Output: 2
Explanation: A vertical line at X = 3 passes through two of the given horizontal lines which are the maximum possible.
This problem is mainly a variation of popular problem called Minimum Platforms.
[Naive Approach] Using Nested Loop – O(n*m) Time and O(1) Space
This approach is based on independently checking the count of every x-axis point that it lies across how many line segments.
- Identify the Range of Vertical Lines: Determine the minimum and maximum x-coordinates from the start and end points of all line segments to define the valid range for vertical lines.
- Check Intersections for Each Vertical Line: For each vertical line within the valid range, check how many line segments intersect with it by comparing the x-coordinate with the start and end points of the segments.
- Track Maximum Intersections: Keep track of the maximum number of line segments that intersect with any vertical line and return this value as the result.
C++
#include <bits/stdc++.h>
using namespace std;
int maxIntersec(vector<vector<int>>& lines) {
int n = lines.size(), maxInt = 0;
int minX = INT_MAX, maxX = INT_MIN;
for (auto& line : lines) {
minX = min(minX, line[0]);
maxX = max(maxX, line[1]);
}
for (int x = minX; x <= maxX; ++x) {
int cnt = 0;
for (auto& line : lines) {
// Check if line intersects vertical line at x
if (line[0] <= x && x <= line[1])
cnt++;
}
maxInt = max(maxInt, cnt);
}
return maxInt;
}
int main() {
vector<vector<int>> lines = {{1, 3}, {5, 6}, {3, 4}};
cout << maxIntersec(lines) << endl;
return 0;
}
Java
import java.util.*;
public class GFG {
public static int maxIntersec(List<int[]> lines) {
int maxInt = 0, minX = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE;
for (int[] line : lines) {
minX = Math.min(minX, line[0]);
maxX = Math.max(maxX, line[1]);
}
for (int x = minX; x <= maxX; ++x) {
int cnt = 0;
for (int[] line : lines) {
// Check if line intersects vertical line at x
if (line[0] <= x && x <= line[1])
cnt++;
}
maxInt = Math.max(maxInt, cnt);
}
return maxInt;
}
public static void main(String[] args) {
List<int[]> lines = Arrays.asList(new int[]{1, 3}, new int[]{2, 3}, new int[]{1, 2}, new int[]{4, 4});
System.out.println(maxIntersec(lines));
}
}
Python
def maxIntersec(lines):
maxInt, minX, maxX = 0, float('inf'), float('-inf')
for line in lines:
minX = min(minX, line[0])
maxX = max(maxX, line[1])
for x in range(minX, maxX + 1):
cnt = 0
for line in lines:
# Check if line intersects vertical line at x
if line[0] <= x <= line[1]:
cnt += 1
maxInt = max(maxInt, cnt)
return maxInt
lines = [[1, 3], [2, 3], [1, 2], [4, 4]]
print(maxIntersec(lines))
C#
using System;
using System.Collections.Generic;
class GFG {
public static int maxIntersec(List<int[]> lines) {
int maxInt = 0, minX = int.MaxValue, maxX = int.MinValue;
foreach (var line in lines) {
minX = Math.Min(minX, line[0]);
maxX = Math.Max(maxX, line[1]);
}
for (int x = minX; x <= maxX; ++x) {
int cnt = 0;
foreach (var line in lines) {
// Check if line intersects vertical line at x
if (line[0] <= x && x <= line[1])
cnt++;
}
maxInt = Math.Max(maxInt, cnt);
}
return maxInt;
}
static void Main() {
var lines = new List<int[]> { new int[] { 1, 3 }, new int[] { 2, 3 }, new int[] { 1, 2 }, new int[] { 4, 4 } };
Console.WriteLine(maxIntersec(lines));
}
}
JavaScript
function maxIntersec(lines) {
let maxInt = 0, minX = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY;
for (let line of lines) {
minX = Math.min(minX, line[0]);
maxX = Math.max(maxX, line[1]);
}
for (let x = minX; x <= maxX; ++x) {
let cnt = 0;
for (let line of lines) {
// Check if line intersects vertical line at x
if (line[0] <= x && x <= line[1])
cnt++;
}
maxInt = Math.max(maxInt, cnt);
}
return maxInt;
}
let lines = [[1, 3], [2, 3], [1, 2], [4, 4]];
console.log(maxIntersec(lines));
Time complexity is O(n*m) where n is the size of list and m is the difference between the max and min x points.
[Better Approach] Using Sorting and Two Pointer – O(n log n) Time and O(n) Space
In this approach, we first sort the start and end points of the line segments. We then use two pointers: one for the start points and one for the end points. If the start point is less than or equal to the end point, it means a new line is starting, so we increase the count of intersections. If the start point is greater than the end point, it means a line has ended, so we decrease the intersection count. At each step, we check and update the maximum number of intersections. This method efficiently tracks the intersections without having to check every single point on the x-axis.
- Sort Start and End Points: The start and end points of all the line segments are sorted to efficiently process the intersections.
- Two Pointer Technique: Traverse through the sorted start and end points using two pointers. Increment the intersection count when a new line starts and decrement when a line ends.
- Track Maximum Intersections: Continuously update the maximum number of active intersections during the traversal and return the result.
C++
#include <bits/stdc++.h>
using namespace std;
int maxIntersec(vector<vector<int>>& lines, int n) {
vector<int> start(n), end(n);
for (int i = 0; i < n; ++i) {
start[i] = lines[i][0];
end[i] = lines[i][1];
}
sort(start.begin(), start.end());
sort(end.begin(), end.end());
int i = 0, j = 0, intersect = 0, maxInter = 0;
while (i < n && j < n) {
// If the next line starts before the current one ends
if (start[i] <= end[j]) {
intersect++;
maxInter = max(maxInter, intersect);
i++;
}
// If a line ends before the next line starts,
else {
intersect--;
j++;
}
}
return maxInter;
}
int main() {
int n = 4;
vector<vector<int>> lines = {{1, 3}, {2, 3}, {1, 2}, {4, 4}};
cout << maxIntersec(lines, n) << endl;
return 0;
}
Java
import java.util.*;
public class GFG {
public static int maxIntersec(List<int[]> lines) {
int n = lines.size();
int[] start = new int[n], end = new int[n];
for (int i = 0; i < n; ++i) {
start[i] = lines.get(i)[0];
end[i] = lines.get(i)[1];
}
Arrays.sort(start);
Arrays.sort(end);
int i = 0, j = 0, intersect = 0, maxInter = 0;
while (i < n && j < n) {
if (start[i] <= end[j]) {
intersect++;
maxInter = Math.max(maxInter, intersect);
i++;
} else {
intersect--;
j++;
}
}
return maxInter;
}
public static void main(String[] args) {
List<int[]> lines = Arrays.asList(new int[]{1, 3}, new int[]{2, 3}, new int[]{1, 2}, new int[]{4, 4});
System.out.println(maxIntersec(lines));
}
}
Python
def maxIntersec(lines):
n = len(lines)
start = [lines[i][0] for i in range(n)]
end = [lines[i][1] for i in range(n)]
start.sort()
end.sort()
i, j, intersect, maxInter = 0, 0, 0, 0
while i < n and j < n:
if start[i] <= end[j]:
intersect += 1
maxInter = max(maxInter, intersect)
i += 1
else:
intersect -= 1
j += 1
return maxInter
lines = [[1, 3], [2, 3], [1, 2], [4, 4]]
print(maxIntersec(lines))
C#
using System;
using System.Collections.Generic;
class Program {
public static int maxIntersec(List<int[]> lines) {
int n = lines.Count;
int[] start = new int[n], end = new int[n];
for (int k = 0; k < n; ++k) {
start[k] = lines[k][0];
end[k] = lines[k][1];
}
Array.Sort(start);
Array.Sort(end);
int i = 0, j = 0, intersect = 0, maxInter = 0;
while (i < n && j < n) {
if (start[i] <= end[j]) {
intersect++;
maxInter = Math.Max(maxInter, intersect);
i++;
} else {
intersect--;
j++;
}
}
return maxInter;
}
static void Main() {
var lines = new List<int[]> { new int[] { 1, 3 }, new int[] { 2, 3 }, new int[] { 1, 2 }, new int[] { 4, 4 } };
Console.WriteLine(maxIntersec(lines));
}
}
JavaScript
function maxIntersec(lines) {
const n = lines.length;
const start = lines.map(line => line[0]);
const end = lines.map(line => line[1]);
start.sort((a, b) => a - b);
end.sort((a, b) => a - b);
let i = 0, j = 0, intersect = 0, maxInter = 0;
while (i < n && j < n) {
if (start[i] <= end[j]) {
intersect++;
maxInter = Math.max(maxInter, intersect);
i++;
} else {
intersect--;
j++;
}
}
return maxInter;
}
const lines = [[1, 3], [2, 3], [1, 2], [4, 4]];
console.log(maxIntersec(lines));
[Expected Approach] Using Hash Map – O(n) Time and O(n) Space
Instead of checking all x-axis points, we focus only on the start and end points of the line segments. We use a map to track these points: incrementing the count when a line starts and decrementing it when a line ends. After processing all points, we simply check the map to find the point with the highest count, which gives the maximum number of intersections. This method is efficient as we only consider the relevant points.
- Create Events: Treat the start of a line as an increment and the end (adjusted by +1) as a decrement to track active line segments.
- Use of Map: Store events in a sorted map where keys are x-coordinates and values are the count of active lines.
- Process Events: Traverse the events, updating the active count at each x-coordinate and track the maximum intersections.
C++
#include <bits/stdc++.h>
using namespace std;
int maxIntersec(vector<vector<int>>& lines) {
unordered_map<int, int> events;
// Create events for each line segment
for (auto& line : lines) {
events[line[0]]++;
events[line[1] + 1]--;
}
int cnt = 0, maxCnt = 0;
for (auto& event : events) {
cnt += event.second;
maxCnt = max(maxCnt, cnt);
}
return maxCnt;
}
int main() {
vector<vector<int>> lines = {{1, 3}, {5, 6}, {3, 4}};
cout << maxIntersec(lines) << endl;
return 0;
}
Java
import java.util.*;
public class GFG {
public static int maxIntersec(List<int[]> lines) {
Map<Integer, Integer> events = new HashMap<>();
// Create events for each line segment
for (int[] line : lines) {
events.put(line[0], events.getOrDefault(line[0], 0) + 1);
events.put(line[1] + 1, events.getOrDefault(line[1] + 1, 0) - 1);
}
int cnt = 0, maxCnt = 0;
for (int value : events.values()) {
cnt += value;
maxCnt = Math.max(maxCnt, cnt);
}
return maxCnt;
}
public static void main(String[] args) {
List<int[]> lines = Arrays.asList(new int[]{1, 3}, new int[]{5, 6}, new int[]{3, 4});
System.out.println(maxIntersec(lines));
}
}
Python
def maxIntersec(lines):
events = {}
# Create events for each line segment
for line in lines:
events[line[0]] = events.get(line[0], 0) + 1
events[line[1] + 1] = events.get(line[1] + 1, 0) - 1
cnt, maxCnt = 0, 0
for value in events.values():
cnt += value
maxCnt = max(maxCnt, cnt)
return maxCnt
lines = [[1, 3], [5, 6], [3, 4]]
print(maxIntersec(lines))
C#
using System;
using System.Collections.Generic;
class Program {
public static int maxIntersec(List<int[]> lines) {
Dictionary<int, int> events = new Dictionary<int, int>();
// Create events for each line segment
foreach (var line in lines) {
if (!events.ContainsKey(line[0]))
events[line[0]] = 0;
events[line[0]]++;
if (!events.ContainsKey(line[1] + 1))
events[line[1] + 1] = 0;
events[line[1] + 1]--;
}
int cnt = 0, maxCnt = 0;
foreach (var eventCount in events.Values) {
cnt += eventCount;
maxCnt = Math.Max(maxCnt, cnt);
}
return maxCnt;
}
static void Main() {
var lines = new List<int[]> { new int[] { 1, 3 }, new int[] { 5, 6 }, new int[] { 3, 4 } };
Console.WriteLine(maxIntersec(lines));
}
}
JavaScript
function maxIntersec(lines) {
let events = {};
// Create events for each line segment
for (let line of lines) {
events[line[0]] = (events[line[0]] || 0) + 1;
events[line[1] + 1] = (events[line[1] + 1] || 0) - 1;
}
let cnt = 0, maxCnt = 0;
for (let value of Object.values(events)) {
cnt += value;
maxCnt = Math.max(maxCnt, cnt);
}
return maxCnt;
}
const lines = [[1, 3], [5, 6], [3, 4]];
console.log(maxIntersec(lines));
Similar Reads
Maximum points of intersection n lines You are given n straight lines. You have to find a maximum number of points of intersection with these n lines.Examples: Input : n = 4 Output : 6 Input : n = 2Output :1 Approach : As we have n number of line, and we have to find the maximum point of intersection using this n line. So this can be don
3 min read
Maximize count of intersecting line segments 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:
8 min read
Find Maximum Number of Intersections on the Chart Given a line chart with n points connected by line segments and a 1-indexed integer array y[], where the ith point has coordinates (i, y[i]). There are no horizontal lines, meaning no two consecutive points have the same y-coordinate. The task is to find the maximum number of points of intersection
14 min read
Maximum possible intersection by moving centers of line segments Given three points on the X-axis which denotes the center of three line segments. The length of the line segment is also given as L. The task is to move the center of the given line segments by a distance of K to maximize the length of intersection between the three lines. Examples: Input: c1 = 1, c
5 min read
Find Maximum number of intersecting points with at most K distance Two players A and B are standing at starting point 0 of an infinite horizontal line. Player A is given an array with jumpA[] of size M and Player B is given an array with jumpB[] of size N. Both players can make jumps as: Player A can jump D distance in both directions (right or left), from its curr
8 min read