Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to the x and y axes.
If there isn't any rectangle, return 0.
Example 1:
Input: [[1,1],[1,3],[3,1],[3,3],[2,2]] Output: 4
Example 2:
Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]] Output: 2
Note:
1 <= points.length <= 500
0 <= points[i][0] <= 40000
0 <= points[i][1] <= 40000
- All points are distinct.
---------------------------------------------------------------
There's no way to improve the algorithm with less than O(n^2)
Solution 1:
from collections import defaultdict
import sys
class Solution:
def minAreaRect(self, points) -> int:
res = sys.maxsize
dic = defaultdict(list)
for point in points:
x,y = point[0],point[1]
dic[x].append(y)
history = {}
for x in sorted(dic.keys()):
yc = sorted(dic[x])
for i,y2 in enumerate(yc):
for j in range(i):
y1 = yc[j]
if (y1,y2) in history:
res = min(res, (y2-y1)*(x-history[(y1,y2)]))
history[(y1,y2)] = x
return 0 if res == sys.maxsize else res
s = Solution()
print(s.minAreaRect([[1,1],[1,3],[3,1],[3,3],[2,2]]))
Solution 2:
For each pair of points in the array, consider them to be the long diagonal of a potential rectangle. We can check if all 4 points are there using a Set.
For example, if the points are (1, 1)
and (5, 5)
, we check if we also have (1, 5)
and (5, 1)
. If we do, we have a candidate rectangle.
class Solution(object):
def minAreaRect(self, points):
S = set(map(tuple, points))
ans = float('inf')
for j, p2 in enumerate(points):
for i in xrange(j):
p1 = points[i]
if (p1[0] != p2[0] and p1[1] != p2[1] and
(p1[0], p2[1]) in S and (p2[0], p1[1]) in S):
ans = min(ans, abs(p2[0] - p1[0]) * abs(p2[1] - p1[1]))
return ans if ans < float('inf') else 0