leetcode 939. Minimum Area Rectangle

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. 1 <= points.length <= 500
  2. 0 <= points[i][0] <= 40000
  3. 0 <= points[i][1] <= 40000
  4. 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:

  1. 在遍历map时,即时在map中只有两个key(1,100),在循环中,按key值遍历,会从1-100依次遍历,而非只遍历1,100两个值。所以,若需要按key遍历map,可以在新建映射时,将key存入一个集合set中,在需要遍历时在集合中查找元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值