题目:
Given a set of points in the
xy
-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to thex
andy
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.
解释:
四个点一定要作为长方形的四个顶点,两点(对角线)确定一个长方形
1.遍历所有的点对,找到所有的点对,最后找到面积最小的,将x相同的点,其y放在一个列表中(或者反过来),也就是建立一个key为x,value为列表的字典。
天哪,为什么python超时?
2.还是这样的思想,还是对角线确定矩阵方法,把遍历过的点放到一个set()
中。
python代码,hashmap思想,超时:
from collections import defaultdict
class Solution:
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
_dict=defaultdict(list)
for point in points:
_dict[point[0]].append(point[1])
min_area=float('inf')
#遍历所有的点对:
n=len(points)
points.sort()
for i in range(n):
for j in range(i+1,n):
x1,y1=points[i]
x2,y2=points[j]
if x1==x2 or y1==y2:
continue
elif (y2 in _dict[x1]) and (y1 in _dict[x2]):
min_area=min(min_area,abs(x1-x2)*abs(y1-y2))
return 0 if min_area==float('inf') else min_area
python代码,set()思想,1500ms,速度极慢:
class Solution:
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
seen=set()
min_area=float('inf')
for x1,y1 in points:
for x2,y2 in seen:
if (x1,y2) in seen and (x2,y1) in seen:
min_area=min(min_area,abs(x1-x2)*abs(y1-y2))
seen.add((x1,y1))
return 0 if min_area==float('inf') else min_area
测试用例有诸如 all points have x = 0 or y = 0的极端情况,下面的代码避免这种情况带来的耗时问题。
一个特别牛逼的字典思想
from collections import defaultdict
class Solution:
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
setx=set()
sety=set()
for point in points:
setx.add(point[0])
sety.add(point[1])
_dict=defaultdict(list)
if len(setx)>len(sety):
for _x,_y in points:
_dict[_x].append(_y)
else:
for _x,_y in points:
_dict[_y].append(_x)
min_area=float('inf')
lastx={}
for x in sorted(_dict):
_dict[x].sort()
for i in range(len(_dict[x])):
#每个点只和自己下面的点比较,求面积的时候不需要求abs了
for j in range(i):
y1,y2=_dict[x][j],_dict[x][i]
if (y1,y2) in lastx:
min_area=min(min_area,(x-lastx[(y1,y2)])*(y2-y1))
lastx[(y1,y2)]=x
return 0 if min_area==float('inf') else min_area
c++代码:
#include <set>
using namespace std;
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
set<int> setx;
set<int> sety;
for (auto point:points)
{
setx.insert(point[0]);
sety.insert(point[1]);
}
map<int ,vector<int>> _map;
if (setx.size()>sety.size())
{
for(auto point :points)
_map[point[0]].push_back(point[1]);
}
else
{
for(auto point :points)
_map[point[1]].push_back(point[0]);
}
int min_area=INT_MAX;
map<vector<int>,int>lastx;
for (auto item:_map)
{
sort(item.second.begin(),item.second.end());
for(int i =0;i<item.second.size();i++)
{
for(int j=0;j<i;j++)
{
int y1=item.second[j];
int y2=item.second[i];
if (lastx.count({y1,y2}))
{
min_area=min(min_area,(item.first-lastx[{y1,y2}])*(y2-y1));
}
lastx[{y1,y2}]=item.first;
}
}
}
return min_area==INT_MAX?0:min_area;
}
};
总结: