Maximum Area Rectangle With Point Constraints II

HARD

Description

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:

Example 1 diagram

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:

Example 2 diagram

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:

Example 3 diagram

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 * 105
  • 0 <= 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

    1. 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.
    1. Pre-process the points into two maps: xMap (mapping each x-coordinate to a sorted list of its y-coordinates) and yMap (mapping each y-coordinate to a sorted list of its x-coordinates).
    1. Initialize maxArea = -1 and a hash map lastYSeen. This map will store, for a pair of x-coordinates (x1, x2), the y-coordinate where they last appeared as an adjacent horizontal segment.
    1. Perform a horizontal sweep by iterating through a sorted list of unique y-coordinates.
    1. For each y, get its sorted list of x-coordinates xCoords from yMap.
    1. Iterate through adjacent pairs (x1, x2) in xCoords. This pair forms an empty horizontal segment.
    1. Check if the pair (x1, x2) exists as a key in lastYSeen. If it does, with a value prevY, we have a candidate rectangle with empty top and bottom edges.
    1. Verify that the vertical edges are also empty. This is done by checking if y is the immediate successor of prevY in the sorted y-lists for both x1 and x2 (from xMap).
    1. If all adjacency conditions hold, calculate the area and update maxArea.
    1. Update lastYSeen with the current (x1, x2) pair and its y-coordinate y.

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

Time Complexity: O(N log N), where N is the number of points. The preprocessing step of creating and sorting the lists in the maps takes `O(N log N)`. The sweep-line itself involves iterating through `O(N)` adjacent pairs in total, with each check involving binary searches (`O(log N)`), leading to a total time complexity of `O(N log N)`.Space Complexity: O(N), where N is the number of points. This space is used for the `xMap`, `yMap`, and the `lastYSeen` map, all of which can store up to `O(N)` elements or pairs in total.

Pros and Cons

Pros:
  • Efficient O(N log N) time complexity, which is suitable for the given constraints.
  • Systematically finds all valid empty rectangles.
Cons:
  • 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



Algorithms:

Sorting

Patterns:

MathGeometry

Data Structures:

ArrayBinary Indexed TreeSegment Tree

Companies:

Subscribe to Scale Engineer newsletter

Learn about System Design, Software Engineering, and interview experiences every week.

No spam, unsubscribe at any time.