You are given an array of points in the X-Y plane points
where points[i] = [xi, yi]
.
Return the minimum area of a rectangle formed from these points, with sides parallel to the X and Y axes. If there is not any such rectangle, return 0
.
Example 1:
Input: points = [[1,1],[1,3],[3,1],[3,3],[2,2]] Output: 4
Example 2:
Input: points = [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]] Output: 2
Constraints:
1 <= points.length <= 500
points[i].length == 2
0 <= xi, yi <= 4 * 104
This problem asks to find the minimum area of a rectangle formed by given points in a 2D plane, with sides parallel to the axes. The solution employs a hash table (dictionary in Python) to efficiently identify pairs of points that form the sides of a rectangle.
Data Preprocessing: The input points
is processed to organize points by their x-coordinates. We use a dictionary (or TreeMap
in Java, map
in C++, or map
in Go) where keys are x-coordinates, and values are lists of corresponding y-coordinates. This structure allows quick access to y-coordinates for a given x.
Iterating and Finding Rectangles: The algorithm iterates through the sorted x-coordinates. For each x-coordinate, it considers all pairs of y-coordinates. If a pair (y1, y2)
has been encountered before with a different x-coordinate (this signifies a rectangle), the area is calculated and compared with the current minimum area (ans
).
Using a Hash Table for Efficiency: A hash table (pos
in the code) stores pairs of (y1, y2)
along with the x-coordinate where they were previously encountered. Checking if a pair exists in pos
takes O(1) average time, making the overall search significantly faster than a brute-force approach that compares all point pairs.
Minimum Area Tracking: The algorithm maintains a variable ans
to store the minimum area found so far. Initially, ans
is set to a large value (infinity or a very large integer). Whenever a smaller rectangle area is found, ans
is updated.
Handling No Rectangles: If no rectangles are found, ans
remains at its initial large value, and the function returns 0.
Time Complexity: O(N log N), where N is the number of points. The sorting of y-coordinates for each x-coordinate contributes to the log N factor. The nested loops iterate through pairs of y-coordinates for each x, which is roughly O(N^2) in the worst case. However, the hash table lookups are O(1) on average, which significantly improves the overall time complexity. Dominating factor becomes the sorting, thus O(N log N).
Space Complexity: O(N) to store the dictionary/map. The space used by pos
is also proportional to the number of unique (y1,y2) pairs, but it's bounded by N in the worst case (all points have different y-values).
The Python code uses a defaultdict(list)
to efficiently manage the points. The inf
constant represents infinity. The code elegantly handles the case where no rectangles are found by returning 0 if ans
remains unchanged (infinity).
from collections import defaultdict
import math
class Solution:
def minAreaRect(self, points: List[List[int]]) -> int:
d = defaultdict(list)
for x, y in points:
d[x].append(y)
pos = {}
ans = math.inf # Use math.inf for infinity
for x in sorted(d):
ys = d[x]
ys.sort()
n = len(ys)
for i, y1 in enumerate(ys):
for y2 in ys[i + 1:]:
if (y1, y2) in pos:
ans = min(ans, (x - pos[(y1, y2)]) * (y2 - y1))
pos[(y1, y2)] = x
return 0 if ans == math.inf else ans
The Java, C++, and Go code follow a similar logic, adapting data structures to their respective language conventions. The key idea of using a hash table for efficient rectangle detection remains consistent across all implementations.