Leetcode 850. 矩形面积 II C++

Leetcode 850. 矩形面积 II

题目

我们给出了一个(轴对齐的)矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标,(x2,y2)是该矩形右上角的坐标。

找出平面中所有矩形叠加覆盖后的总面积。 由于答案可能太大,请返回它对 10 ^ 9 + 7 取模的结果。
在这里插入图片描述

测试样例

示例 1:

输入:[[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示。

示例 2:

输入:[[0,0,1000000000,1000000000]]
输出:49
解释:答案是 10^18 对 (10^9 + 7) 取模的结果, 即 (10^9)^2 → (-7)^2 = 49 。

提示:

  • 1 <= rectangles.length <= 200
  • rectanges[i].length = 4
  • 0 <=rectangles[i][j] <= 109 矩形叠加覆盖后的总面积不会超越 263 - 1 ,这意味着可以用一个 64位有符号整数来保存面积结果。

题解

我们按照x轴进行遍历。我们首先将所有的x坐标用set集合进行记录。我们依次选取最近的两个x坐标,找到矩形中在这区间的纵轴部分。将纵轴按照区间对的形式经行插入,即合并共同区间。然后遍历所有的纵轴区间就能得到当前横轴区间对应的矩形面积了。
详细过程见代码

代码

	void addY(vector<vector<long>>& list,int y1,int y2){		//插入区间[y1,y2],共同部分需要合并
        int n = list.size(),i;
        for(i=0; i<n; i++){				//找到要插入的部分
            if(list[i][1] >= y1)    break;  
        }
        if(i == n)  list.push_back({y1,y2});		//在最后进行插入
        else if(list[i][0] > y2){		//没有共同区间,直接插入
            list.insert(list.begin()+i,{y1,y2});
        }else{
            if(y1<=list[i][0])  list[i][0] = y1;		//插入区间后部分与i区间前部分相交。合并需要改变i的起点
            if(y2>list[i][1]){		//插入区间后部分 和i及之后的区间相交
                list[i][1] = y2;
                int j = i;
                while(j < n){		//找到最后一个相交区间
                    if(list[j][1]<=y2)  j++;
                    else    break;
                }

                if(j == n)  list.erase(list.begin()+i+1,list.end());		//都囊括了,故i及之后的直接删除
                else if(list[j][0]<=y2){		//插入区间后部分和j区间前部分相交
                    list[i][1] = list[j][1];		//将i区间的右边界改为j区间的右边界
                    list.erase(list.begin()+i+1,list.begin()+j+1);
                }else{		//插入区间和j区间不相交,且囊括了i+1~j-1区间
                    list.erase(list.begin()+i+1,list.begin()+j);
                }
            }  
        }
    }
    int rectangleArea(vector<vector<int>>& rectangles) {
        int n = rectangles.size();
        int mod = pow(10,9)+7;
        set<long> x;
        for(int i=0; i<n; i++){
            x.insert(rectangles[i][0]);
            x.insert(rectangles[i][2]);
        }
        set<long>::iterator iter = x.begin();
        set<long>::iterator next = iter;
        next++;
        int ans=0;
        while(next != x.end()){			//遍历每个x区间对,[iter,next]
            vector<vector<long>> y;
            for(int i=0; i<n; i++){		//找到输入[iter,next]的矩形,将y坐标插入到区间对中
                if(rectangles[i][0]<=(*iter) && rectangles[i][2]>=(*next)){
                    addY(y,rectangles[i][1],rectangles[i][3]);
                }
            }

            for(int i=0; i<y.size(); i++){			//统计当前x坐标下的面积
                ans = (ans+((*next)-(*iter))*(y[i][1]-y[i][0])%mod)%mod;
            }
            iter++;
            next++;
        }
        return ans;
    }

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rectangle-area-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值