• 入门力扣自学笔记151 C++ (题目编号850)


    850. 矩形面积 II

    题目:

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

    计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次 。

    返回 总面积 。因为答案可能太大,返回 109 + 7 的 模 。


    示例 1:

    输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
    输出:6
    解释:如图所示,三个矩形覆盖了总面积为6的区域。
    从(1,1)到(2,2),绿色矩形和红色矩形重叠。
    从(1,0)到(2,3),三个矩形都重叠。


    示例 2:

    输入: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


    代码:

    1. class Solution
    2. {
    3. private:
    4. const static int MOD = 1e9 + 7;
    5. const static int OPEN = 0;
    6. const static int CLOSE = 1;
    7. // 计算宽度:其实就是不断累加更大的x的差值即可
    8. int QueryWidth(multisetint,int>>& activate)
    9. {
    10. int res = 0;
    11. int maxX = -1;
    12. for (auto [x1, x2] : activate)
    13. {
    14. maxX = max(maxX, x1);
    15. // 如果x变大了,则计算差值累加更大的宽度
    16. res += max(0, x2 - maxX);
    17. // 不断更新最大x
    18. maxX = max(maxX, x2);
    19. }
    20. return res;
    21. }
    22. public:
    23. int rectangleArea(vectorint>>& rectangles)
    24. {
    25. vectorint>> rec;
    26. for (auto v: rectangles)
    27. {
    28. rec.push_back({v[1], OPEN, v[0], v[2]});
    29. rec.push_back({v[3], CLOSE, v[0], v[2]});
    30. }
    31. // 排序从下到上来扫描
    32. sort(rec.begin(), rec.end());
    33. // 存储面积和
    34. int res = 0;
    35. // 初始化第一个y的位置
    36. int lastY = rec[0][0];
    37. // 当前需要计算的面积横坐标 [x1,x2]
    38. // 扫描过程中 对于每次OPEN则插入,CLOSE则删除
    39. multisetint,int>> activate;
    40. for (const vector<int> r : rec)
    41. {
    42. int y = r[0];
    43. int state = r[1];
    44. int x1 = r[2];
    45. int x2 = r[3];
    46. // 累加面积
    47. res = (res + (long long)QueryWidth(activate)*(y-lastY)) % MOD;
    48. // 更新上一个y坐标
    49. lastY = y;
    50. // 对于每次OPEN则插入,CLOSE则删除
    51. if (state == OPEN)
    52. {
    53. activate.insert({x1, x2});
    54. }
    55. else
    56. {
    57. activate.erase(activate.find(pair<int,int>{x1, x2}) );
    58. }
    59. }
    60. return res;
    61. }
    62. };

  • 相关阅读:
    拯救工程师,远程开发C++的四大秘笈|视频教程
    动态代理之Cjlib的动态代理简单理解
    智能采购管理系统有哪些应用优势?如何高效提升医药制造业采购管理效率?
    jquery 事件和事件对象
    jvm调优-cpu飙升及响应慢
    vscode虚拟环境使用jupyter
    C-Pack: Packaged Resources To Advance General Chinese Embedding
    数据安全技术专利态势分析
    【SQLServer】并行的保留线程和已使用线程
    图解AVLTree
  • 原文地址:https://blog.csdn.net/DK_Sorhic/article/details/126883233