1637. Widest Vertical Area Between Two Points Containing No Points
Problem Description
You are given n
points on a 2D plane, where each point is represented as points[i] = [xi, yi]
with xi
being the x-coordinate and yi
being the y-coordinate.
The task is to find the widest vertical area between two points such that no other points exist inside this area.
A vertical area is defined as:
- A region with fixed width that extends infinitely in both the positive and negative y-directions (infinite height)
- Bounded by two vertical lines parallel to the y-axis
- The width is the horizontal distance between these two vertical lines
Key constraints to note:
- Points that lie exactly on the boundary (edge) of the vertical area are not considered to be inside the area
- You need to find the maximum possible width among all valid vertical areas
In simpler terms, imagine drawing vertical lines through some of the given points. You need to find the largest horizontal gap between any two consecutive vertical lines where no points exist strictly between them (points on the lines themselves are allowed).
For example, if you have points at x-coordinates [1, 3, 8, 10]
, the gaps between consecutive x-values are 2
, 5
, and 2
. The widest vertical area would have width 5
(between x = 3 and x = 8).
Intuition
When looking for the widest vertical area with no points inside, we need to think about what creates these "empty" vertical areas. Since a vertical area extends infinitely along the y-axis, the y-coordinates of the points don't actually matter - only the x-coordinates determine where the vertical boundaries can be placed.
The key insight is that the widest empty vertical area must be bounded by two points from our dataset. Why? Because if we try to place a vertical boundary at any x-coordinate that doesn't contain a point, we could always move it closer to the nearest point to make the area wider without including any new points inside.
This means we're essentially looking for the largest gap between x-coordinates of our points. To find this systematically:
- We only care about the x-coordinates of all points
- The potential vertical areas are the gaps between consecutive x-values when arranged in order
- We need to find the maximum among all these gaps
By sorting the points by their x-coordinates, we line them up from left to right on the plane. The width of each possible vertical area is simply the difference between consecutive x-values in this sorted order. For instance, if after sorting we have x-coordinates [1, 3, 8, 10]
, the possible widths are 3-1=2
, 8-3=5
, and 10-8=2
.
The solution becomes straightforward: sort the points by x-coordinate, calculate all gaps between consecutive points, and return the maximum gap. This is why the code sorts the points and then uses pairwise
to look at each consecutive pair (a, b)
, calculating b[0] - a[0]
(the difference in x-coordinates) and finding the maximum of all such differences.
Learn more about Sorting patterns.
Solution Approach
The implementation follows a straightforward approach based on our intuition:
Step 1: Sort the points
points.sort()
- We sort the entire points array using Python's built-in
sort()
method - By default, Python sorts lists of lists by the first element (x-coordinate), then by the second element (y-coordinate) if needed
- Since we only care about x-coordinates for finding vertical gaps, this default behavior works perfectly
- Time complexity:
O(n log n)
wheren
is the number of points
Step 2: Find consecutive differences
pairwise(points)
- The
pairwise
function (from Python'sitertools
) creates an iterator of consecutive pairs - For a sorted list like
[[1,2], [3,4], [8,1], [10,5]]
, it generates pairs:([1,2], [3,4])
,([3,4], [8,1])
,([8,1], [10,5])
- This allows us to examine each adjacent pair of points efficiently
Step 3: Calculate maximum gap
max(b[0] - a[0] for a, b in pairwise(points))
- For each consecutive pair
(a, b)
, we calculate the horizontal distance:b[0] - a[0]
a[0]
represents the x-coordinate of the left pointb[0]
represents the x-coordinate of the right point- The generator expression computes all these differences
- The
max()
function returns the largest difference, which is our answer
Complete Solution Flow:
- Input:
points = [[8,7],[9,9],[7,4],[9,7]]
- After sorting:
[[7,4],[8,7],[9,9],[9,7]]
- Consecutive differences:
8-7=1
,9-8=1
,9-9=0
- Maximum difference:
1
Time Complexity: O(n log n)
- dominated by the sorting step
Space Complexity: O(1)
- if we don't count the space used by sorting (in-place sort), otherwise O(n)
for the sorting algorithm's temporary space
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to illustrate the solution approach.
Example Input: points = [[3,2], [9,5], [1,7], [3,8], [7,1]]
Step 1: Extract and visualize x-coordinates
Looking at our points, the x-coordinates are: 3, 9, 1, 3, 7
(The y-coordinates don't matter for finding vertical areas)
Step 2: Sort the points by x-coordinate
After sorting: [[1,7], [3,2], [3,8], [7,1], [9,5]]
The sorted x-coordinates are: 1, 3, 3, 7, 9
Step 3: Find consecutive gaps Now we examine each pair of consecutive x-values:
- Gap between x=1 and x=3:
3 - 1 = 2
- Gap between x=3 and x=3:
3 - 3 = 0
(duplicate x-values) - Gap between x=3 and x=7:
7 - 3 = 4
- Gap between x=7 and x=9:
9 - 7 = 2
Step 4: Find the maximum gap
The gaps are: [2, 0, 4, 2]
Maximum gap = 4
Visual representation:
x: 1 3 7 9 | | | | <-2-> 0 <-4-> <-2-> ^^^^ widest area
The widest vertical area is between x=3 and x=7 with width 4. This area contains no points inside it (the points at x=3 and x=7 are on the boundaries, which is allowed).
Code execution trace:
points = [[3,2], [9,5], [1,7], [3,8], [7,1]] points.sort() # [[1,7], [3,2], [3,8], [7,1], [9,5]] # pairwise generates: ([1,7],[3,2]), ([3,2],[3,8]), ([3,8],[7,1]), ([7,1],[9,5]) # Differences: 3-1=2, 3-3=0, 7-3=4, 9-7=2 # max(2, 0, 4, 2) = 4
The answer is 4
.
Solution Implementation
1class Solution:
2 def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
3 # Sort points by x-coordinate (first element of each point)
4 points.sort()
5
6 # Find the maximum gap between consecutive x-coordinates
7 max_width = 0
8 for i in range(1, len(points)):
9 # Calculate the difference between current and previous x-coordinate
10 width = points[i][0] - points[i-1][0]
11 # Update maximum width if current width is larger
12 max_width = max(max_width, width)
13
14 return max_width
15```
16
17Note: The original code uses `pairwise` which is available in Python 3.10+ from itertools. Here's an alternative version if you want to keep the pairwise approach:
18
19```python3
20from itertools import pairwise
21from typing import List
22
23class Solution:
24 def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
25 # Sort points by x-coordinate (first element of each point)
26 points.sort()
27
28 # Find maximum width between consecutive vertical lines
29 # pairwise creates pairs of consecutive elements: (p1, p2), (p2, p3), ...
30 return max(second[0] - first[0] for first, second in pairwise(points))
31
1class Solution {
2 /**
3 * Finds the maximum width of a vertical area between any two points.
4 * The width is defined as the horizontal distance between consecutive x-coordinates.
5 *
6 * @param points 2D array where each element represents a point [x, y]
7 * @return the maximum width between any two consecutive vertical lines
8 */
9 public int maxWidthOfVerticalArea(int[][] points) {
10 // Sort points by x-coordinate in ascending order
11 Arrays.sort(points, (point1, point2) -> point1[0] - point2[0]);
12
13 // Initialize variable to track maximum width
14 int maxWidth = 0;
15
16 // Iterate through consecutive points to find maximum horizontal distance
17 for (int i = 0; i < points.length - 1; i++) {
18 // Calculate the horizontal distance between current and next point
19 int currentWidth = points[i + 1][0] - points[i][0];
20
21 // Update maximum width if current width is larger
22 maxWidth = Math.max(maxWidth, currentWidth);
23 }
24
25 return maxWidth;
26 }
27}
28
1class Solution {
2public:
3 int maxWidthOfVerticalArea(vector<vector<int>>& points) {
4 // Sort points by x-coordinate (first element of each point)
5 sort(points.begin(), points.end());
6
7 // Initialize the maximum width to 0
8 int maxWidth = 0;
9
10 // Iterate through consecutive points to find the maximum gap
11 for (int i = 0; i < points.size() - 1; ++i) {
12 // Calculate the horizontal distance between consecutive points
13 int currentWidth = points[i + 1][0] - points[i][0];
14
15 // Update maximum width if current width is larger
16 maxWidth = max(maxWidth, currentWidth);
17 }
18
19 // Return the maximum width found
20 return maxWidth;
21 }
22};
23
1/**
2 * Finds the maximum width between consecutive vertical lines formed by points
3 * @param points - Array of 2D points where each point is [x, y]
4 * @returns The maximum width between any two consecutive vertical lines
5 */
6function maxWidthOfVerticalArea(points: number[][]): number {
7 // Sort points by x-coordinate in ascending order
8 points.sort((a: number[], b: number[]) => a[0] - b[0]);
9
10 // Initialize maximum width to 0
11 let maxWidth: number = 0;
12
13 // Iterate through sorted points to find maximum gap between consecutive x-coordinates
14 for (let i: number = 1; i < points.length; i++) {
15 // Calculate width between current and previous point's x-coordinates
16 const currentWidth: number = points[i][0] - points[i - 1][0];
17
18 // Update maximum width if current width is larger
19 maxWidth = Math.max(maxWidth, currentWidth);
20 }
21
22 return maxWidth;
23}
24
Time and Space Complexity
Time Complexity: O(n log n)
The time complexity is dominated by the sorting operation points.sort()
, which takes O(n log n)
time where n
is the number of points. After sorting, the code iterates through consecutive pairs of points using pairwise()
, which takes O(n)
time to generate pairs and compute differences. The max()
function also runs in O(n)
time. Therefore, the overall time complexity is O(n log n) + O(n) = O(n log n)
.
Space Complexity: O(n)
The space complexity depends on the sorting algorithm used by Python's sort()
method. Python uses Timsort, which has a worst-case space complexity of O(n)
. Additionally, pairwise()
creates an iterator that generates pairs on-the-fly, but the generator expression (b[0] - a[0] for a, b in pairwise(points))
is consumed by max()
, which only needs O(1)
additional space to track the maximum value. Therefore, the overall space complexity is O(n)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Handle Duplicate X-Coordinates
One of the most common mistakes is not realizing that multiple points can share the same x-coordinate. When this happens, the width between these points is 0, which might be overlooked.
Example of the pitfall:
points = [[1,2], [3,4], [3,8], [5,6]] # After sorting: [[1,2], [3,4], [3,8], [5,6]] # Gap between [3,4] and [3,8] is 0 (same x-coordinate)
Why this matters: If you're not careful with the implementation, you might accidentally skip these zero-width gaps or handle them incorrectly. While the current solution handles this correctly (since 3 - 3 = 0
is a valid calculation), developers might be tempted to "optimize" by skipping duplicate x-coordinates, which could lead to incorrect indexing.
2. Attempting to Use Only X-Coordinates (Set-Based Approach)
A tempting optimization is to extract only the unique x-coordinates using a set, then find the maximum gap:
Incorrect approach:
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
# WRONG: This loses duplicate x-coordinates
x_coords = sorted(set(point[0] for point in points))
return max(x_coords[i+1] - x_coords[i] for i in range(len(x_coords)-1))
The problem: While this seems more efficient, it has a critical edge case. When there's only one unique x-coordinate (all points lie on the same vertical line), the function will crash because there are no consecutive pairs to compare.
Correct handling:
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
x_coords = sorted(set(point[0] for point in points))
# Handle edge case: all points on same vertical line
if len(x_coords) == 1:
return 0
return max(x_coords[i+1] - x_coords[i] for i in range(len(x_coords)-1))
3. Not Handling Edge Cases Properly
Several edge cases can trip up implementations:
Edge Case 1: Only two points
points = [[1,1], [3,3]] # Should return 2, not crash or return 0
Edge Case 2: All points on the same vertical line
points = [[5,1], [5,2], [5,3]] # Should return 0, as there's no gap between different x-coordinates
Robust solution that handles all cases:
class Solution:
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
# Extract and sort unique x-coordinates
x_coords = sorted(set(point[0] for point in points))
# If all points are on the same vertical line
if len(x_coords) <= 1:
return 0
# Find maximum gap between consecutive x-coordinates
max_width = 0
for i in range(1, len(x_coords)):
width = x_coords[i] - x_coords[i-1]
max_width = max(max_width, width)
return max_width
This approach is actually more efficient as it eliminates duplicate x-coordinates, reducing the number of comparisons needed while properly handling all edge cases.
Which data structure is used to implement priority queue?
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!