Maximum Area Rectangle With Point Constraints II
HARDDescription
There are n points on an infinite plane. You are given two integer arrays xCoord and yCoord where (xCoord[i], yCoord[i]) represents the coordinates of the ith point.
Your task is to find the maximum area of a rectangle that:
- Can be formed using four of these points as its corners.
- Does not contain any other point inside or on its border.
- Has its edges parallel to the axes.
Return the maximum area that you can obtain or -1 if no such rectangle is possible.
Example 1:
Input: xCoord = [1,1,3,3], yCoord = [1,3,1,3]
Output: 4
Explanation:

We can make a rectangle with these 4 points as corners and there is no other point that lies inside or on the border. Hence, the maximum possible area would be 4.
Example 2:
Input: xCoord = [1,1,3,3,2], yCoord = [1,3,1,3,2]
Output: -1
Explanation:

There is only one rectangle possible is with points [1,1], [1,3], [3,1] and [3,3] but [2,2] will always lie inside it. Hence, returning -1.
Example 3:
Input: xCoord = [1,1,3,3,1,3], yCoord = [1,3,1,3,2,2]
Output: 2
Explanation:

The maximum area rectangle is formed by the points [1,3], [1,2], [3,2], [3,3], which has an area of 2. Additionally, the points [1,1], [1,2], [3,1], [3,2] also form a valid rectangle with the same area.
Constraints:
1 <= xCoord.length == yCoord.length <= 2 * 1050 <= xCoord[i], yCoord[i] <= 8 * 107- All the given points are unique.
Approaches
Checkout 3 different approaches to solve Maximum Area Rectangle With Point Constraints II. Click on different approaches to view the approach and algorithm in detail.
Sweep-Line Algorithm
This approach improves upon the brute-force method by using a sweep-line technique. It processes the points sorted by one coordinate (e.g., y-coordinate) and uses a hash map to keep track of potential rectangle edges seen so far. This avoids the O(N^3) complexity by intelligently constructing and verifying only the rectangles that have a chance of being empty.
Algorithm
-
- Establish the necessary and sufficient conditions for an empty rectangle: its four edges must be empty of other points. This implies that its corners are formed by points that are mutually adjacent in the point-defined grid.
-
- Pre-process the points into two maps:
xMap(mapping each x-coordinate to a sorted list of its y-coordinates) andyMap(mapping each y-coordinate to a sorted list of its x-coordinates).
- Pre-process the points into two maps:
-
- Initialize
maxArea = -1and a hash maplastYSeen. This map will store, for a pair of x-coordinates(x1, x2), the y-coordinate where they last appeared as an adjacent horizontal segment.
- Initialize
-
- Perform a horizontal sweep by iterating through a sorted list of unique y-coordinates.
-
- For each
y, get its sorted list of x-coordinatesxCoordsfromyMap.
- For each
-
- Iterate through adjacent pairs
(x1, x2)inxCoords. This pair forms an empty horizontal segment.
- Iterate through adjacent pairs
-
- Check if the pair
(x1, x2)exists as a key inlastYSeen. If it does, with a valueprevY, we have a candidate rectangle with empty top and bottom edges.
- Check if the pair
-
- Verify that the vertical edges are also empty. This is done by checking if
yis the immediate successor ofprevYin the sorted y-lists for bothx1andx2(fromxMap).
- Verify that the vertical edges are also empty. This is done by checking if
-
- If all adjacency conditions hold, calculate the area and update
maxArea.
- If all adjacency conditions hold, calculate the area and update
-
- Update
lastYSeenwith the current(x1, x2)pair and its y-coordinatey.
- Update
The core idea is based on the insight that an empty rectangle must be bounded by adjacent points. For a rectangle with corners (x1, y1), (x2, y1), (x1, y2), (x2, y2) to be empty, its horizontal and vertical edges must not contain any other points.
We can implement this with a horizontal sweep-line algorithm. We first pre-process all points into two maps: one mapping x-coordinates to their sorted y-coordinates (xMap), and another mapping y-coordinates to their sorted x-coordinates (yMap).
We then sweep a line from bottom to top by iterating through the unique y-coordinates in sorted order. At each y level, we look at the points on that line. We consider every adjacent pair of points (x1, y) and (x2, y). This forms an empty horizontal segment. We use a hash map, lastYSeen, to remember the y-coordinate where we last saw the horizontal segment defined by (x1, x2).
If we find the pair (x1, x2) in our map, it means we have found a previous empty horizontal segment at prevY with the same x-coordinates. This gives us a rectangle with empty top and bottom edges. The final step is to verify that the vertical edges are also empty. We do this by using our xMap to check if y is the immediate successor of prevY in the sorted y-lists for both x1 and x2. If this holds, the rectangle is empty, and we update our maximum area.
import java.util.*;
class Solution {
public long maxAreaRectangle(int[] xCoord, int[] yCoord) {
int n = xCoord.length;
Map<Integer, List<Integer>> xMap = new HashMap<>();
Map<Integer, List<Integer>> yMap = new HashMap<>();
for (int i = 0; i < n; i++) {
xMap.computeIfAbsent(xCoord[i], k -> new ArrayList<>()).add(yCoord[i]);
yMap.computeIfAbsent(yCoord[i], k -> new ArrayList<>()).add(xCoord[i]);
}
for (List<Integer> list : xMap.values()) {
Collections.sort(list);
}
for (List<Integer> list : yMap.values()) {
Collections.sort(list);
}
List<Integer> sortedY = new ArrayList<>(yMap.keySet());
Collections.sort(sortedY);
long maxArea = -1;
Map<Long, Integer> lastYSeen = new HashMap<>();
for (int y : sortedY) {
List<Integer> xCoords = yMap.get(y);
for (int i = 0; i < xCoords.size() - 1; i++) {
int x1 = xCoords.get(i);
int x2 = xCoords.get(i + 1);
long pairKey = pack(x1, x2);
if (lastYSeen.containsKey(pairKey)) {
int prevY = lastYSeen.get(pairKey);
// Check vertical adjacency
if (isVerticallyAdjacent(xMap, x1, prevY, y) && isVerticallyAdjacent(xMap, x2, prevY, y)) {
long area = (long)(x2 - x1) * (y - prevY);
if (maxArea == -1 || area > maxArea) {
maxArea = area;
}
}
}
lastYSeen.put(pairKey, y);
}
}
return maxArea;
}
private boolean isVerticallyAdjacent(Map<Integer, List<Integer>> xMap, int x, int y1, int y2) {
List<Integer> yList = xMap.get(x);
int idx = Collections.binarySearch(yList, y1);
return idx >= 0 && idx + 1 < yList.size() && yList.get(idx + 1) == y2;
}
private long pack(int x1, int x2) {
return ((long)x1 << 32) | x2;
}
}
Complexity Analysis
Pros and Cons
- Efficient
O(N log N)time complexity, which is suitable for the given constraints. - Systematically finds all valid empty rectangles.
- The implementation is more complex than the brute-force approach.
- Requires careful management of multiple data structures and understanding of the geometric properties.
Video Solution
Watch the video walkthrough for Maximum Area Rectangle With Point Constraints II
Similar Questions
5 related questions you might find useful
Algorithms:
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.