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.
题目给定一系列的点,计算由这些点能构成的最小矩形的面积。
因为只有最多只有500个点,因此是可以暴力过的。
首先选定某一列上的两个点,查找与这两个点相同行的位置上,是否存在两个共列的点,如果有,那么可以构成一个矩形,再计算面积,更新答案
inline bool mmp(vector<int>& a,vector<int>& b){
if(a[0]==b[0])
return a[1]<b[1];
return a[0]<b[0];
}
class Solution {
private:
set<int> column;
map<int,vector<pair<int,int> > > hor,ver;
map<pair<int,int>,bool> vis;
public:
int minAreaRect(vector<vector<int>>& points) {
int len=points.size();
if(len<4)
return 0;
sort(points.begin(),points.end(),mmp);
for(int i=0;i<len;i++){
hor[points[i][1]].push_back(make_pair(points[i][0],points[i][1]));
ver[points[i][0]].push_back(make_pair(points[i][0],points[i][1]));
if(column.find(points[i][0])==column.end())
column.insert(points[i][0]);
}
int ans=INT_MAX;
for(auto k : column){
if(ver[k].size()==0)
continue;
for(int i=0;i<ver[k].size();i++){
pair<int,int> star=make_pair(k,ver[k][i].second);
pair<int,int> finish=make_pair(-1,-1);
for(int j=i+1;j<ver[k].size();j++){
int a=0,b=0;
finish=make_pair(-1,-1);
while(a<hor[ver[k][i].second].size() && b<hor[ver[k][j].second].size()){
while(vis.find(hor[ver[k][i].second][a])!=vis.end()){
a++;
}
while(vis.find(hor[ver[k][j].second][b])!=vis.end()){
b++;
}
if(hor[ver[k][i].second][a].first==hor[ver[k][j].second][b].first && hor[ver[k][i].second][a].first!=k){
finish=hor[ver[k][j].second][b];
break;
}else
if(hor[ver[k][i].second][a].first<hor[ver[k][j].second][b].first)
a++;
else
b++;
}
if(finish.first!=-1)
ans=min(ans,getArea(star,finish));
}
vis[ver[k][i]]=true;
}
}
if(ans==INT_MAX)
return 0;
else
return ans;
}
inline void showPair(pair<int,int>& a){
cout<<"first="<<a.first<<" second="<<a.second<<endl;
}
inline int abs(int a){
if(a<0)
return -a;
return a;
}
inline int getArea(pair<int,int>& a,pair<int,int>& b){
return abs(a.first-b.first)*abs(a.second-b.second);
}
};
Note:
- 在遍历map时,即时在map中只有两个key(1,100),在循环中,按key值遍历,会从1-100依次遍历,而非只遍历1,100两个值。所以,若需要按key遍历map,可以在新建映射时,将key存入一个集合set中,在需要遍历时在集合中查找元素