我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标, (xi1, yi1) 是该矩形 左下角 的坐标, (xi2, yi2) 是该矩形 右上角 的坐标。
计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次 。
返回 总面积 。因为答案可能太大,返回 109 + 7 的 模 。

输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示,三个矩形覆盖了总面积为6的区域。
从(1,1)到(2,2),绿色矩形和红色矩形重叠。
从(1,0)到(2,3),三个矩形都重叠。
输入:rectangles = [[0,0,1000000000,1000000000]]
输出:49
解释:答案是 1018 对 (109 + 7) 取模的结果, 即 49 。
1 <= rectangles.length <= 200
rectanges[i].length = 4
0 <= xi1, yi1, xi2, yi2 <= 109
矩形叠加覆盖后的总面积不会超越 2^63 - 1 ,这意味着可以用一个 64 位有符号整数来保存面积结果。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/rectangle-area-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
本质题目其实就是去计算面积,那么其实问题并不难
从下往上扫描,计算每一段之间的最大宽度,那么y的差值乘以宽度就是面积
为了扫描计算的准确,需要额外辅助
需要按照y排序,从小到大
需要对于当前区间内的范围x也进行排序,考虑x范围会有重复用一个multiset来保存
对于离开区间需要删除multiset里的key,进入则插入key
计算时候从x1,x2里x1小的开始计算,这样子就能算出最大的宽度,参见函数 QueryWidth
- class Solution
- {
- private:
- const static int MOD = 1e9 + 7;
- const static int OPEN = 0;
- const static int CLOSE = 1;
-
- // 计算宽度:其实就是不断累加更大的x的差值即可
- int QueryWidth(multiset
int ,int>>& activate) - {
- int res = 0;
- int maxX = -1;
- for (auto [x1, x2] : activate)
- {
- maxX = max(maxX, x1);
- // 如果x变大了,则计算差值累加更大的宽度
- res += max(0, x2 - maxX);
- // 不断更新最大x
- maxX = max(maxX, x2);
- }
- return res;
- }
-
- public:
- int rectangleArea(vector
int >>& rectangles) - {
- vector
int>> rec; - for (auto v: rectangles)
- {
- rec.push_back({v[1], OPEN, v[0], v[2]});
- rec.push_back({v[3], CLOSE, v[0], v[2]});
- }
- // 排序从下到上来扫描
- sort(rec.begin(), rec.end());
-
- // 存储面积和
- int res = 0;
- // 初始化第一个y的位置
- int lastY = rec[0][0];
- // 当前需要计算的面积横坐标 [x1,x2]
- // 扫描过程中 对于每次OPEN则插入,CLOSE则删除
- multiset
int,int>> activate; -
- for (const vector<int> r : rec)
- {
- int y = r[0];
- int state = r[1];
- int x1 = r[2];
- int x2 = r[3];
-
- // 累加面积
- res = (res + (long long)QueryWidth(activate)*(y-lastY)) % MOD;
- // 更新上一个y坐标
- lastY = y;
- // 对于每次OPEN则插入,CLOSE则删除
- if (state == OPEN)
- {
- activate.insert({x1, x2});
- }
- else
- {
- activate.erase(activate.find(pair<int,int>{x1, x2}) );
- }
- }
-
- return res;
- }
- };