【区间合并 差分 栈】3169. 无需开会的工作日

本文涉及知识点

区间合并
差分数组(大约2024年7月1号发)

LeetCode3169. 无需开会的工作日

给你一个正整数 days,表示员工可工作的总天数(从第 1 天开始)。另给你一个二维数组 meetings,长度为 n,其中 meetings[i] = [start_i, end_i] 表示第 i 次会议的开始和结束天数(包含首尾)。
返回员工可工作且没有安排会议的天数。
注意:会议时间可能会有重叠。

示例 1:
输入:days = 10, meetings = [[5,7],[1,3],[9,10]]
输出:2
解释:
第 4 天和第 8 天没有安排会议。
示例 2:
输入:days = 5, meetings = [[2,4],[1,3]]
输出:1
解释:
第 5 天没有安排会议。
示例 3:
输入:days = 6, meetings = [[1,6]]
输出:0
解释:
所有工作日都安排了会议。
提示:
1 <= days <= 109
1 <= meetings.length <= 105
meetings[i].length == 2
1 <= meetings[i][0] <= meetings[i][1] <= days

差分

days最大109,所以不能有差分数组,只能用差分map,求和的需要有序。
统计开会的时间,比不开会的时间简单。
mDiff[si]++ mDiff[ei+1]-- 表示[si,ei] 一场会议。
∀ \forall mDiff的键 key,其下一个键为nkey。
∀ \forall k ∈ \in [key,nkey) mDiff[k]都为0,省略。
即:
x = ∑ i : 0 k e y m D i f f [ i ] = ∑ i : 0 k m D i f f [ i ] x = \sum_{i:0}^{key}mDiff[i] \quad = \sum_{i:0}^{k}mDiff[i] x=i:0keymDiff[i]=i:0kmDiff[i]
如果x不为0,则[key,nkey)全部要开会。

核心代码

class Solution {
public:
	int countDays(int days, vector<vector<int>>& meetings) {
		map<int, int> mDiff;
		for (const auto& v : meetings) {
			mDiff[v[0]]++;
			mDiff[v[1] + 1]--;
		}
		int iRet = 0;
		int sum = 0;
		for (auto it = mDiff.begin(); std::next(it) != mDiff.end(); ++it) {
			auto itNext = std::next(it);
			sum += it->second;
			if (sum > 0) {
				iRet += itNext->first - it->first;
			}
		}
		return  days - iRet;
	}
};

单元测试

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
{
	int days;
	vector<vector<int>> meetings;
	TEST_CLASS(UnitTest)
	{
	public:
	
		TEST_METHOD(TestMethod1)
		{
			days = 5, meetings = { {2,4},{1,3} };
			auto res = Solution().countDays(days, meetings);
			AssertEx(1, res);
		}
	
	};
}

封装类

template<class KEY=int,class VALUE=int>
class CMapDiff
{
public:
	void Set(KEY left, KEY rExclue, VALUE value) {
		m_mDiff[left]+= value;
		m_mDiff[rExclue]-= value;
	}
	vector<pair<KEY, VALUE>> Ans()const {
		vector<pair<KEY, VALUE>> res;
		VALUE sum = 0;
		for (const auto& [key,value]: m_mDiff) {			
			sum += value;
			res.emplace_back(make_pair(key, sum));
		}
		return res;
	}
protected:
	map<KEY, VALUE> m_mDiff;
};
class Solution {
public:
	int countDays(int days, vector<vector<int>>& meetings) {
		CMapDiff mDiff;
		for (const auto& v : meetings) {
			mDiff.Set(v[0], v[1] + 1,1);
		}
		auto v = mDiff.Ans();
		int iRet = 0;
		for (int i = 0; i + 1 < v.size(); i++) {
			if( v[i].second > 0 ){ iRet += v[i + 1].first - v[i].first; }			
		}
		return  days - iRet;
	}
};

差分(旧版)

值相同的区间进行了合并,没多大意义。

class Solution {
public:
	int countDays(int days, vector<vector<int>>& meetings) {
		map<int, int> mDiff;
		for (const auto& v : meetings) {
			mDiff[v[0]]++;
			mDiff[v[1]+1]--;
		}

		vector<pair<int, int>> v;
		if (1 != mDiff.begin()->first) {
			v.emplace_back(make_pair(1, 0));
		}
		int sum = 0;
		for (const auto& [day, cnt] : mDiff) {
			sum += cnt;
			v.emplace_back(day, (sum>0));
		}		
		vector<pair<int, int>> v1;
		v1.emplace_back(v[0]);
		for (int i = 1; i < v.size(); i++) {
			if (v[i].second != v1.back().second) {
				v1.emplace_back(v[i]);
			}
		}
		if (v1.back().first <= days) {
			v1.emplace_back(make_pair(days + 1, 0));
		}
		int ret = 0;
		for (int i = 0; i + 1 < v1.size(); i++) {
			if (0 == v1[i].second) {
				ret += v1[i + 1].first - v1[i].first;
			}
		}
		return ret;
	}
};

区间合并

先按开始时间的升序排序。依次入栈,如果当前元素和栈顶元素能合并则合并:开始时间不变,终止时间取两者最大值;否则,直接入栈。

template<class ELE>
void MaxSelf(ELE* seft, const ELE& other)
{
	*seft = max(*seft, other);
}

class Solution {
public:
	int countDays(int days, vector<vector<int>>& meetings) {
		sort(meetings.begin(), meetings.end(), [&](const auto& v1, const auto& v2) {return v1[0] < v2[0]; });
		stack<pair<int, int>> sta;
		for (const auto& v : meetings) {
			if (sta.empty() || (sta.top().second < v[0])) {
				sta.emplace(make_pair(v[0], v[1] + 1));
			}
			else {
				MaxSelf(&sta.top().second, v[1] + 1);
			}
		}
		int iRet = 0;
		while (sta.size()) {
			iRet += sta.top().second - sta.top().first;
			sta.pop();
		}
		return  days - iRet;
	}
};

封装后

class CIntervalMerging
{
public:
	CIntervalMerging( vector<vector<int>> vInterval,bool bIncludeEnd) {
		sort(vInterval.begin(), vInterval.end(), [&](const auto& v1, const auto& v2) {return v1[0] < v2[0]; });
		for (const auto& v : vInterval) {
			if (V.empty() || (V.back().second < v[0])) {
				V.emplace_back(make_pair(v[0], v[1] + bIncludeEnd));
			}
			else {
				V.back().second = max(V.back().second, v[1] + bIncludeEnd);
			}
		}
	}
	vector<pair<int, int>> V;
};
class Solution {
public:
	int countDays(int days, vector<vector<int>>& meetings) {	
		CIntervalMerging im(meetings, true);
		int iRet = std::accumulate(im.V.begin(), im.V.end(), 0, [](auto val, auto pr) {return val + pr.second - pr.first; });
		return  days - iRet;
	}
};

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

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

相关推荐

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝牙模块的安全性与隐私保护

蓝牙模块作为现代无线通信的重要组成部分&#xff0c;在智能家居、可穿戴设备、健康监测等多个领域得到了广泛应用。然而&#xff0c;随着蓝牙技术的普及&#xff0c;其安全性和隐私保护问题也日益凸显。本文将探讨蓝牙模块在数据传输过程中的安全性问题&#xff0c;分析隐私保…

Web应用安全测试-业务功能滥用(二)

Web应用安全测试-业务功能滥用&#xff08;二&#xff09; 7、未验证的URL跳转 漏洞描述&#xff1a;服务端未对传入的跳转url变量进行检查和控制&#xff0c;可能导致可恶意构造任意一个恶意地址&#xff0c;诱导用户跳转到恶意网站。由于是从可信的站点跳转出去的&#xff…

如何扩展自己的外部竞争力

前言 程序员是一个需要不断学习的职业&#xff0c;面对层出不穷的新技术&#xff0c;假如你不能够保持一个不断学习的热情。那么&#xff0c;在未来的就业市场中&#xff0c;可能优势会不太明显。那么&#xff0c;除了提高自己内部的技术竞争力外&#xff0c;有什么渠道可以提…

Linux下的GPIO编程

目录 一、前言 二、sysfs方式 1、sysfs简介 2、基本目录结构 3、编号计算 4、sysfs方式控制GPIO 三、libgpiod库 1、libgpiod库简介 2、API函数 四、LED灯编程 一、前言 在Linux下&#xff0c;我们通常使用 sysfs 和 libgpiod库 两种方式进行控制GPIO&#xff0c;目前…

哈喽GPT-4o——对GPT-4o Prompt的思考与看法

目录 一、提示词二、提示词的优势1、提升理解能力2、增强专注力3、提高效率 三、什么样的算无效提示词&#xff1f;1、过于宽泛2、含糊不清3、太过复杂4、没有具体上下文5、缺乏明确目标6、过于开放7、使用专业术语但未定义8、缺乏相关性&#xff1a; 四、提示词正确的编写步骤…

ofd文件预览

文件列表 <template><div><div classfile v-if$myUtils.coll.isNotEmpty(filesList)><div classfile-view><div classfile-view-item :style{justifyContent: align } v-for(item, index) in filesList :keyindex><img classfile-view-item-…

纵深发力 持续推进,富格林平台发展势头喜人

自2024年2月1日正式上线以来,富格林互联网投融资平台已迅速崛起,吸引了业内专家学者的高度认可以及广大投资者的青睐。平台规模持续扩大,目前累计注册用户已超过10万人,总投资额突破50亿美元。这一卓越表现不仅体现了平台的稳健运营和出色的投资项目,也展示了其在互联网投融资领…

产品应用 | 小盒子跑大模型!英码科技基于算能BM1684X平台实现大模型私有化部署

当前&#xff0c;在人工智能领域&#xff0c;大模型在丰富人工智能应用场景中扮演着重要的角色&#xff0c;经过不断的探索&#xff0c;大模型进入到落地的阶段。而大模型在落地过程中面临两大关键难题&#xff1a;对庞大计算资源的需求和对数据隐私与安全的考量。为应对这些挑…

typora+Picgo使用Lsky pro搭建本地服务图床

typoraPicgo使用Lsky pro搭建本地服务图床 Picgo下载lankong插件lankong插件安装Auth token获取 Picgo测试typora测试问题说明 Picgo下载 Picgo下载&#xff1a;https://github.com/Molunerfinn/PicGo/releases&#xff0c;注意&#xff1a;请直接使用尝鲜版&#xff0c;正式版…

一文让你清晰了解医疗行业采购堡垒机的必要性

医疗行业&#xff0c;一个与大家息息相关的行业。随着医疗行业的快速发展和信息化建设的深入推进&#xff0c;传统网络安全防护手段已经难以满足现代医疗信息系统的安全需求&#xff0c;特别是在处理敏感的患者信息和保障医院内部数据安全方面。因此采购堡垒机是非常必要的。 堡…

python310: pip install Could not install packages (HTTPSConnectionPool)问题

一、问题描述 在使用pip install安装包或者升级pip版本&#xff08;pip install --upgrade pip&#xff09;时遇到以下错误&#xff1a; WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ReadTimeoutError(…

github ssh key的SHA256是什么

github ssh key的SHA256是什么 怎么知道github上自己的公钥指纹和本地的公钥是否一致&#xff1f; 计算方法如下&#xff1a; cat .ssh/id_rsa.pub |awk { print $2 } | # Only the actual key data without prefix or commentsbase64 -d | # decode as base64s…

面向对象编程重载

系列文章目录 文章目录 系列文章目录前言一、重载&#xff08;overload&#xff09; 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了…

现货白银实时交易平台的成长阶段 你出在哪个阶段?

很多人喜欢在现货白银平台上做模拟交易&#xff0c;因为他们认为现货白银实时交易平台上交易太痛苦了&#xff0c;不光随时会面临风险&#xff0c;而且还可能让自己出现大的亏损。如果投资者认为痛苦&#xff0c;那笔者觉得投资者不妨将在现货白银实时交易平台上做交易&#xf…

nodejs 某音douyin网页端搜索接口及x_bogus、a_bogus(包含完整源码)(2024-06-13)

前言 x_bogus或a_bogus算法大概是对数据、ua、时间戳、浏览器的几个指纹进行计算&#xff0c;拿到一个110位大数组&#xff0c;然后转字符&#xff0c;在头部再添加十二位随机字符&#xff0c;再进行魔改的base64加密。 问&#xff1a;抖音的x_bogus、a_bogus值有什么用&#x…

win10 双显卡,双显示器,VGA那个经常出现息屏(待机后无法唤醒),必须重启才能解决,(图文)手把手教你如何处理简单愉快的解决。

一、问题 双显示器&#xff08;双显卡&#xff0c;其中一个是HDMI&#xff0c;一个是VGA&#xff09;window系统&#xff08;本机win10&#xff09;&#xff0c;经常莫名出现&#xff0c;在待机或者主动息屏后&#xff0c;VGA显示器无法唤醒&#xff0c;依然黑屏&#xff0c;不…

蚂蚁集团:2023年科研投入211.9亿元

6月13日&#xff0c;蚂蚁集团发布2023年可持续发展报告。报告显示&#xff0c;2023年蚂蚁集团科研投入达到211.9亿元&#xff0c;再创历史新高&#xff0c;蚂蚁科技投入的重点是人工智能和数据要素技术。 蚂蚁集团董事长兼CEO井贤栋在报告致辞中说&#xff0c;面向未来&#x…

Java项目:110 springboot夕阳红公寓管理系统的设计与实现

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统有管理员&#xff0c;租客 管理员权限操作的功能包括对租客&#xff0c;访客&#xff0c;缴费&#xff0c;维修&#xff0c;留言&#xff0c;公…

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project&#xff0c;选择Import Legacy CCSv3.3 Porjects…&#xff0c;弹出对话框&#xff0c;通过Browse…按钮导入一个3.3版本的工程项目&#xff1b; 选择.pjt文件&#xff0c;选择Copy projects into worlkspace 右击选择P…

2001-2023年上市公司数字化转型测算数据(含原始数据+处理代码+计算结果)

2001-2023年上市公司数字化转型测算数据&#xff08;含原始数据处理代码计算结果&#xff09;&#xff08;吴非&#xff09; 1、时间&#xff1a;2001-2023年 2、来源&#xff1a;上市公司年报 3、指标:行业代码、行业名称、证券简称、是否发生ST或ST或PT、是否发生暂停上市…