【离散化 二维差分】850. 矩形面积 II

本文涉及知识点

离散化 二维差分

LeetCode850. 矩形面积 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

离散化、二维差分

注意: 忽略xi1 等于 xi2或yi1等于yi2得。确保xi1<xi2和yi1<yi2。
一,利用vCodex将所有xi1,xi2编码。
二,vCodey将所有yi1,yi2编码。
三,利用二维差分记录那些点(编码)被覆盖。
令点x1,y1被覆盖则 面积为(vCodex[x1+1]-vCodex[x1])*(vCodey[y1+1]-vCodey[y1])

代码

核心代码

template<int MOD = 1000000007>
class C1097Int
{
public:C1097Int(long long llData = 0) :m_iData(llData% MOD){}C1097Int  operator+(const C1097Int& o)const{return C1097Int(((long long)m_iData + o.m_iData) % MOD);}C1097Int& operator+=(const C1097Int& o){m_iData = ((long long)m_iData + o.m_iData) % MOD;return *this;}C1097Int& operator-=(const C1097Int& o){m_iData = (m_iData + MOD - o.m_iData) % MOD;return *this;}C1097Int  operator-(const C1097Int& o){return C1097Int((m_iData + MOD - o.m_iData) % MOD);}C1097Int  operator*(const C1097Int& o)const{return((long long)m_iData * o.m_iData) % MOD;}C1097Int& operator*=(const C1097Int& o){m_iData = ((long long)m_iData * o.m_iData) % MOD;return *this;}C1097Int  operator/(const C1097Int& o)const{return *this * o.PowNegative1();}C1097Int& operator/=(const C1097Int& o){*this /= o.PowNegative1();return *this;}bool operator==(const C1097Int& o)const{return m_iData == o.m_iData;}bool operator<(const C1097Int& o)const{return m_iData < o.m_iData;}C1097Int pow(long long n)const{C1097Int iRet = 1, iCur = *this;while (n){if (n & 1){iRet *= iCur;}iCur *= iCur;n >>= 1;}return iRet;}C1097Int PowNegative1()const{return pow(MOD - 2);}int ToInt()const{return m_iData;}
private:int m_iData = 0;;
};
class CDiscretize //离散化
{
public:CDiscretize(vector<int> nums){sort(nums.begin(), nums.end());nums.erase(std::unique(nums.begin(), nums.end()), nums.end());m_nums = nums;for (int i = 0; i < nums.size(); i++){m_mValueToIndex[nums[i]] = i;}}int operator[](const int value)const{auto it = m_mValueToIndex.find(value);if (m_mValueToIndex.end() == it){return -1;}return it->second;}int size()const{return m_mValueToIndex.size();}vector<int> m_nums;
protected:	unordered_map<int, int> m_mValueToIndex;
};template<class T = int >
class CDiff2
{
public:CDiff2(int r, int c):m_iR(r),m_iC(c) {m_vDiff.assign(m_iR, vector<T>(m_iC));}void Set(int r1, int c1, int r2Exinc, int c2Exinc,int iAdd) {m_vDiff[r1][c1] += iAdd;m_vDiff[r2Exinc][c2Exinc] += iAdd;m_vDiff[r1][c2Exinc] -= iAdd;m_vDiff[r2Exinc][c1] -= iAdd;}vector<vector<T>> Ans()const {vector<vector<T>> res(m_iR, vector<T>(m_iC));vector<T> vCols(m_iC);for (int r = 0; r < m_iR; r++) {T iSum = 0;for (int c = 0; c < m_iC; c++) {vCols[c] += m_vDiff[r][c];iSum += vCols[c];res[r][c] = iSum;}}return res;}const int m_iR, m_iC;
protected:vector<vector<T>> m_vDiff;
};
class Solution {
public:int rectangleArea(vector<vector<int>>& rectangles) {vector<vector<int>> tmp;vector<int> xs, ys;for (auto& v : rectangles) {if ((v[0] == v[2]) || (v[1] == v[3])) { continue; }if (v[0] > v[2]) { swap(v[0], v[2]); }if (v[1] > v[3]) { swap(v[1], v[3]); }tmp.emplace_back(v);xs.emplace_back(v[0]);xs.emplace_back(v[2]);ys.emplace_back(v[1]);ys.emplace_back(v[3]);}CDiscretize xCode(xs), yCode(ys);CDiff2<> diff(xCode.size() + 1, yCode.size() + 1);for (const auto& v : tmp) {diff.Set(xCode[v[0]], yCode[v[1]],xCode[v[2]], yCode[v[3]],1);}auto res = diff.Ans();C1097Int<> biRet;for (int r = 0; r+1 < diff.m_iR; r++) {			for (int c = 0; c+1 < diff.m_iC; c++) {				if (res[r][c] > 0) {C1097Int<> cur = ((long long)xCode.m_nums[r + 1] - xCode.m_nums[r]) * (yCode.m_nums[c + 1] - yCode.m_nums[c]);biRet += cur;}}}return biRet.ToInt();}
};

单元测试

template<class T1,class T2>
void AssertEx(const T1& t1, const T2& t2)
{Assert::AreEqual(t1 , t2);
}template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{Assert::AreEqual(v1.size(), v2.size());	for (int i = 0; i < v1.size(); i++){Assert::AreEqual(v1[i], v2[i]);}
}template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{sort(vv1.begin(), vv1.end());sort(vv2.begin(), vv2.end());Assert::AreEqual(vv1.size(), vv2.size());for (int i = 0; i < vv1.size(); i++){AssertEx(vv1[i], vv2[i]);}
}namespace UnitTest
{vector<vector<int>> rectangles;TEST_CLASS(UnitTest){public:TEST_METHOD(TestMethod0){rectangles = { {0,0,2,2},{1,0,2,3},{1,0,3,1} };auto res = Solution().rectangleArea(rectangles);AssertEx( 6, res);}TEST_METHOD(TestMethod1){rectangles = { {0,0,1000000000,1000000000} };auto res = Solution().rectangleArea(rectangles);AssertEx(49, res);}TEST_METHOD(TestMethod2){rectangles = { {93516, 44895, 94753, 69358}, { 13141,52454,59740,71232 }, { 22877,11159,85255,61703 }, { 11917,8218,84490,36637 }, { 75914,29447,83941,64384 }, { 22490,71433,64258,74059 }, { 18433,51177,87595,98688 }, { 70854,80720,91838,92304 }, { 46522,49839,48550,94096 }, { 95435,37993,99139,49382 }, { 10618,696,33239,45957 }, { 18854,2818,57522,78807 }, { 61229,36593,76550,41271 }, { 99381,90692,99820,95125 } };auto res = Solution().rectangleArea(rectangles);AssertEx(971243962, res);}};
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/352583.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十七课,海龟画图习题课(一)

图案一&#xff0c;半圆 import turtleturtle.circle(50, 180)turtle.left(90)turtle.forward(100) 图案二&#xff0c;同心圆 import turtleturtle.circle(100)turtle.right(90)turtle.penup()turtle.forward(50)turtle.pendown()turtle.left(90)turtle.circle(150) 图案三&am…

上海亚商投顾:沪指缩量调整 PCB概念股持续爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 大小指数昨日走势分化&#xff0c;沪指全天震荡调整&#xff0c;创业板指午后涨超1%。消费电子板块全天强势&a…

持续学习的综述: 理论、方法与应用

摘要 为了应对现实世界的动态&#xff0c;智能系统需要在其整个生命周期中增量地获取、更新、积累和利用知识。这种能力被称为持续学习&#xff0c;为人工智能系统自适应发展提供了基础。从一般意义上讲&#xff0c;持续学习明显受到灾难性遗忘的限制&#xff0c;在这种情况下…

新手如何入门Web3?

一、什么是Web3&#xff1f; Web3是指下一代互联网&#xff0c;它基于区块链技术&#xff0c;致力于将各种在线活动变得更加安全、透明和去中心化。Web3是一个广义的概念&#xff0c;涵盖了包括数字货币、去中心化应用、智能合约等在内的多个方面。它的主要特点包括去中心化、…

深度学习 --- stanford cs231学习笔记四(神经网络的几大重要组成部分)

训练神经网络1 1&#xff0c;激活函数&#xff08;activation functions&#xff09; 激活函数是神经网络之于线性分类器的最大进步&#xff0c;最大贡献&#xff0c;即&#xff0c;引入了非线性。 1&#xff0c;1 Sigmoid sigmoid函数的性质&#xff1a; 结合指数函数的图像可…

element-plus的Tour 漫游式引导怎么去绑定Cascader 级联选择器

首先官方例子是用的button 官方.$el这个log出来是&#xff1a; 知道是以元素为准就拿对应的元素就行 级联选择器.$el是这样的&#xff1a; 你可以移入这个元素部分去看看是哪个要用的&#xff08;好像火狐直接放上去就可以看到元素表示&#xff0c;谷歌要双击或者右键选择去看…

[深度学习]--分类问题的排查错误的流程

原因复现&#xff1a; 原生的.pt 好使&#xff0c; 转化后的 CoreML不好使&#xff0c; 分类有问题。 yolov8 格式的支持情况 Format Argument Suffix CPU GPU 0 PyTorch - .pt True True 1 Tor…

C#——析构函数详情

析构函数 C# 中的析构函数&#xff08;也被称作“终结器”&#xff09;同样是类中的一个特殊成员函数&#xff0c;主要用于在垃圾回收器回收类实例时执行一些必要的清理操作。 析构函数: 当一个对象被释放的时候执行 C# 中的析构函数具有以下特点&#xff1a; * 析构函数只…

C语言 | Leetcode C语言题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; int findPeakElement(int* nums, int numsSize) {int ls_max0;for(int i1;i<numsSize;i){if(nums[ls_max]>nums[i]);else{ls_maxi;}}return ls_max; }

Pycharm怎么默认终端连接远程服务器

因为经常需要从宿舍到学校内通勤&#xff0c;期间所有连接都会中断&#xff0c;所以每次开SSH特别麻烦&#xff0c;每次终端自动切换到本地&#xff1a; 每次都得点一下Start SSH Session 想要默认终端连接远程服务器&#xff0c;需要点File->Setting->Tools->SSH T…

无代码爬虫软件八爪鱼采集器-如何设计判断是、否

我们在设计采集规则的时候&#xff0c;可能会需要判断&#xff0c;比如采集评论的时候“展开更多回复”&#xff0c;就点击这个按钮&#xff0c;像这种情况就可以设计一个判断模块进入 判断模块添加后会自动生成两个&#xff0c;默认都是不判断直接执行&#xff0c;如果我们需要…

ROS实验课(三)

write in advance 此次实验课给我的生活来了沉重的一击&#xff0c;不单单是因为没有做出来&#xff0c;还因为我卡在了 插件 缺失 而无法解决。之前对待实验课&#xff0c;能在操作流程之外有暇思考具体的实现&#xff0c;此次只能记录简单的操作流程部分。 老规矩&#xff…

保姆级pycharm远程连接linux服务器

1、登录服务器&#xff0c;创建账号。 一般都是管理员账户登录&#xff0c;创建自己的账号。如果不需要&#xff0c;可跳过这步。 打开MobaXterm&#xff0c;点击左上角Session创建会话。 再点击左上角SSH&#xff0c;分别输入服务器ip和账号&#xff0c;最后点ok&#xff0c;进…

cloud_enum:一款针对不同平台云环境安全的OSINT工具

关于cloud_enum cloud_enum是一款功能强大的云环境安全OSINT工具&#xff0c;该工具支持AWS、Azure和Google Cloud三种不同的云环境&#xff0c;旨在帮助广大研究人员枚举目标云环境中的公共资源&#xff0c;并尝试寻找其中潜在的安全威胁。 功能介绍 当前版本的cloud_enum支…

Unity2D游戏制作入门 | 13 ( 之人物三段攻击 )

上期链接&#xff1a;Unity2D游戏制作入门 | 12(之人物受伤和死亡的逻辑动画)-CSDN博客 上期我们聊了人物的受伤和死亡的逻辑和动画&#xff0c;我们主要学习了事件的执行&#xff0c;即我们在人物受伤时可能会触发很多的事件&#xff0c;比如触发人物受伤的动画以及播放音乐等…

MinIO Enterprise Cache:实现超性能的分布式 DRAM 缓存

随着计算世界的发展和 DRAM 价格的暴跌&#xff0c;我们发现服务器配置通常配备 500GB 或更多的 DRAM。当您处理大型部署时&#xff0c;即使是那些具有超高密度 NVMe 驱动器的部署&#xff0c;这些服务器上的服务器数量乘以 DRAM 也会迅速增加&#xff0c;通常达到几 TB。该 DR…

【电脑日常问题】关于“已经安装了该产品的另一个版本”解决方法

问题描述: 在安装应用或者某游戏时弹出该窗口,虽然游戏已经安装完成,但是游戏无法正常运行。 原因分析: 出现这个问题,大概率可能是某次游戏安装完成,点击开始游戏的时候会自动安装一个软件,但是点了取消,以致于这个程序安装中断,但是已安装的部分还残留,目前是P社的…

Redis常见数据类型及其常用命令详解

文章目录 一、Redis概述二、Redis常用命令1.通用命令1.1 KEYS&#xff1a;查看符合模板的所有 key1.2 DEL&#xff1a;删除一个指定的 key1.3 EXISTS&#xff1a;判断 key 是否存在1.4 EXPIRE&#xff1a;给一个 key 设置有效期&#xff0c;有效期到期时该 key 会被自动删除1.5…

Ubuntu乌班图安装VIM文本编辑器工具

系列文章目录 Ubuntu-24.04-live-server-amd64安装界面中文版 Ubuntu-24.04-live-server-amd64启用ssh Ubuntu安装qemu-guest-agent 文章目录 系列文章目录前言一、安装VIM&#xff1f;二、VIM基本设置总结 前言 从centos转到Ubuntu发现默认安装没有vi 一、安装VIM&#xff1…

SpringBoot Vue Bootstrap 旅游管理系统

SpringBoot Vue 旅游管理系统源码&#xff0c;附带环境安装&#xff0c;运行说明 源码地址 开发环境 jdk1.8,mysql8,nodejs16,navicat,idea 使用技术springboot mybatis vue bootstrap 部分功能截图预览