【二分查找】【区间合并】LeetCode2589:完成所有任务的最少时间

作者推荐

【动态规划】【广度优先】LeetCode2258:逃离火灾

本文涉及的基础知识点

二分查找算法合集 有序向量的二分查找,向量只会在尾部增加删除。

题目

你有一台电脑,它可以 同时 运行无数个任务。给你一个二维整数数组 tasks ,其中 tasks[i] = [starti, endi, durationi] 表示第 i 个任务需要在 闭区间 时间段 [starti, endi] 内运行 durationi 个整数时间点(但不需要连续)。
当电脑需要运行任务时,你可以打开电脑,如果空闲时,你可以将电脑关闭。
请你返回完成所有任务的情况下,电脑最少需要运行多少秒。
示例 1:
输入:tasks = [[2,3,1],[4,5,1],[1,5,2]]
输出:2
解释:

  • 第一个任务在闭区间 [2, 2] 运行。
  • 第二个任务在闭区间 [5, 5] 运行。
  • 第三个任务在闭区间 [2, 2] 和 [5, 5] 运行。
    电脑总共运行 2 个整数时间点。
    示例 2:
    输入:tasks = [[1,3,2],[2,5,3],[5,6,2]]
    输出:4
    解释:
  • 第一个任务在闭区间 [2, 3] 运行
  • 第二个任务在闭区间 [2, 3] 和 [5, 5] 运行。
  • 第三个任务在闭区间 [5, 6] 运行。
    电脑总共运行 4 个整数时间点。
    参数范围
    1 <= tasks.length <= 2000
    tasks[i].length == 3
    1 <= starti, endi <= 2000
    1 <= durationi <= endi - starti + 1

分析

时间复杂度: O(nlogn)。枚举任务时间复杂度O(n),每个任务二分查找,时间复杂度O(logn)。将任务按结束时间排序的时间复杂度也是O(nlogn)。
如果运行的时间不够,尽量在靠近结束时间的运行。

变量解析

vEndLenTotalLen电脑运行的时间段,升序,时间段间无重叠。第一个元素:结束时间;第二个元素,本次运行时间;第三个时间段:本时间段及之前的时间段总运行时间。
iHasLen已已有时间,本次任务能运行的时间。
(get<0>(*it) - max(curBegin, v[0]) + 1)当前任务,it时间段能运行的时间
curNotUseit及之前的时间段,当前任务无法运行的时间。it后的时间段当前任务一定能运行。
(v[1] - get<0>(vEndLenTotalLen.back()) <= iNeedAdd)新加的时间段,需要和之前的时间段合并么?

代码

核心代码

class Solution {
public:int findMinimumTime(vector<vector<int>>& tasks) {sort(tasks.begin(), tasks.end(), [](const auto& v1, const auto& v2) {return v1[1] < v2[1]; });vector<tuple<int, int,int>> vEndLenTotalLen;for (const auto& v : tasks){const auto it = std::lower_bound(vEndLenTotalLen.begin(), vEndLenTotalLen.end(),v[0], [](const auto& t, const int i) {return get<0>(t) < i; });int iHasLen = 0;if ((vEndLenTotalLen.end() != it)){const int curBegin = get<0>(*it) - get<1>(*it) + 1;const int curNotUse = get<2>(*it) - (get<0>(*it) - max(curBegin, v[0]) + 1);iHasLen = get<2>(vEndLenTotalLen.back())  - curNotUse;}int iNeedAdd = v[2] - iHasLen;if (iNeedAdd <= 0 ){continue;}while (vEndLenTotalLen.size() && (v[1] - get<0>(vEndLenTotalLen.back()) <= iNeedAdd)){iNeedAdd += get<1>(vEndLenTotalLen.back());vEndLenTotalLen.pop_back();}vEndLenTotalLen.emplace_back(v[1], iNeedAdd, iNeedAdd + (vEndLenTotalLen.empty() ? 0 : get<2>(vEndLenTotalLen.back())));}return get<2>(vEndLenTotalLen.back());}
};

测试用例


template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){assert(v1[i] == v2[i]);}
}template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}int main()
{vector<vector<int>> tasks;{Solution slu;tasks = { {2,3,1},{4,5,1},{1,5,2} };auto res = slu.findMinimumTime(tasks);Assert(2, res);}{Solution slu;tasks = tasks = { {1,3,2},{2,5,3},{5,6,2} };auto res = slu.findMinimumTime(tasks);Assert(4, res);}
}

2023年9月版

class Solution {
public:
int findMinimumTime(vector<vector>& tasks) {
sort(tasks.begin(), tasks.end(), [](const vector& v1, const vector& v2)
{
return v1[1] < v2[1];
});
std::multimap<int, pair<int, int>> mEndToLenTotalLen;
int iTotalLen = 0;
for (const auto& v : tasks)
{
int lenShare = 0;//可以和前面共享的时间段
auto it = mEndToLenTotalLen.lower_bound(v[0]);
if( mEndToLenTotalLen.end()!= it)
{
lenShare = min(it->second.first, it->first - v[0] + 1);
lenShare = min(lenShare, v[2]);
lenShare += iTotalLen - it->second.second;
}
int iNeed = v[2] - lenShare;
if (iNeed <= 0)
{
continue;
}
iTotalLen += iNeed;
while(mEndToLenTotalLen.size()&&(v[1] - iNeed <= mEndToLenTotalLen.rbegin()->first))
{
iNeed += mEndToLenTotalLen.rbegin()->second.first;
mEndToLenTotalLen.erase(std::prev(mEndToLenTotalLen.end()));
}
// std::cout << v[1] << " " << iNeed << std::endl;
mEndToLenTotalLen.emplace(v[1], std::make_pair(iNeed, iTotalLen));
}
return iTotalLen;
}
};

2023年第一版

class Solution {
public:
int findMinimumTime(vector<vector>& tasks) {
std::sort(tasks.begin(), tasks.end(), [](const vector& v1, const vector& v2)
{
return v1[1] < v2[1];
});
const int iMaxDay = tasks.back()[1];
vector vWork(iMaxDay + 1);
int iRet = 0;
for (const auto& v : tasks)
{
int iNeedWork = v[2];
for (int i = v[0]; i <= v[1]; i++)
{
if (vWork[i])
{
iNeedWork–;
}
}
for (int i = v[1]; iNeedWork > 0; i–)
{
if (!vWork[i])
{
vWork[i] = true;
iNeedWork–;
iRet++;
}
}
}
return iRet;
}
};

2023年第二版

 class Solution {public:int findMinimumTime(vector<vector<int>>& tasks) {std::sort(tasks.begin(), tasks.end(), [](const vector<int>& v1, const vector<int>& v2){return v1[1] < v2[1];});vector<std::tuple<int, int, int>> vBeginEndTotalWork;vBeginEndTotalWork.emplace_back(-2, -2, 0);for (const auto& v : tasks){int iNeedWork = v[2];auto it = std::lower_bound(vBeginEndTotalWork.begin(), vBeginEndTotalWork.end(), v[0], [](const std::tuple<int, int, int>& t, const int i){return std::get<0>(t) < i;});--it;iNeedWork -= std::get<2>(vBeginEndTotalWork.back()) - std::get<2>(*it);if (v[0] <= std::get<1>(*it)){iNeedWork -= std::get<1>(*it) - v[0] + 1;}if (iNeedWork <= 0){continue;}while (v[1] - std::get<1>(vBeginEndTotalWork.back()) <= iNeedWork){iNeedWork += (std::get<1>(vBeginEndTotalWork.back()) - std::get<0>(vBeginEndTotalWork.back()) + 1);vBeginEndTotalWork.pop_back();}vBeginEndTotalWork.emplace_back(v[1] - iNeedWork + 1, v[1], std::get<2>(vBeginEndTotalWork.back())+iNeedWork);}return std::get<2>(vBeginEndTotalWork.back());}};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.mzph.cn/news/218078.shtml

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

相关文章

圣诞节酷炫特效合集【含十几个HTML+CSS前端特效+34个桌面酷炫圣诞程序】

写在前面 ❤️源码获取:订阅后见文末 ❤️内容介绍:包含HTML+CSS等十几个圣诞特效;以及三十四个桌面酷炫圣诞树合集 ❤️订阅后所得如下: ❤️HTML圣诞+桌面圣诞程序效果如下: 下方展示代码仅举例其中几个 所有效果源码及文件订阅后找博主获取即可 🎄css3圣诞雪人动…

基于python的大数据分析与应用环境的搭建

一、主要目的&#xff1a; 初步熟悉Python数据分析工具&#xff0c;通过查阅相关说明文档掌握Numpy、Scipy和Pandas包的基本使用方法。对于不同形式的源数据文件&#xff0c;能够基于python开发环境正确的完成数据导入。 二、主要内容&#xff1a; 1、Python开发环境安装以及…

阿里云国际跨境直播解决方案,视频AI创新营销模式丰富直播场景

据第三方咨询公司iiMedia Research预测&#xff0c;2017-2020年&#xff0c;视频直播行业一直处于高速发展阶段。2020年&#xff0c;视频直播行业市场收入超1万亿元&#xff0c;累计覆盖用户5.26亿。 视频直播的应用范围已从视频娱乐、电子商务等泛互联网行业扩展到在线教育、…

分布式数据库 GaiaDB-X 金融应用实践

1 银行新一代核心系统建设背景及架构 在银行的 IT 建设历程中&#xff0c;尤其是中大行&#xff0c;大多都基于大型机和小型机来构建核心系统。随着银行业务的快速发展&#xff0c;这样的系统对业务的支持越来越举步维艰&#xff0c;主要体现在以下四个方面&#xff1a; 首先…

[C++] 继承

文章目录 1、继承的概念及定义1.1 继承的概念1.2 继承的定义1.2.1 定义格式1.2.2 继承关系和访问限定符1.2.3 继承基类成员访问方式的变化 2、基类和派生类对象赋值转换3、继承中的作用域4、派生类的默认成员函数5、继承与友元6、继承与静态成员7、菱形继承&#xff0c;菱形虚拟…

centOS 64位安装node_exporter

下载node_exporter 我是在这里https://prometheus.io/download/#node_exporter下载到自己电脑&#xff0c;然后使用rz命令传到linux上的。 关于rz命令的使用可看我的这个文章linux上传下载文件lrzsz 解压 tar -xzf node_exporter-1.7.0.linux-amd64.tar.gz将执行文件移动到b…

数据中心到底是如何工作的?

数字时代的数据中心&#xff0c;就如同网络世界的心脏&#xff0c;它的鼓动关系到整个网络生态的运转。但这个复杂而庞大的数据枢纽背后隐藏着怎样的精密机制&#xff0c;是许多人颇感好奇的谜。 数字时代的数据中心&#xff0c;就如同网络世界的心脏&#xff0c;它的鼓动关系…

Python爬虫实战 | 爬取拼多多商品的详情价格SKU数据

本案例将为大家演示如何爬取拼多多商品的详情数据。目的是爬取大量的商品以及商品的评论&#xff0c;所以在程序设计上要考虑到该爬虫的高并发以及持久化存储。爬虫工具选用了Scrapy框架&#xff0c;以满足爬虫的高并发请求任务&#xff1b;持久化存储用了MongoDB&#xff0c;对…

Epicypher—CUTANA™ ChIC/CUTRUN Kit

核酸酶靶向切割和释放 (CUT&RUN)技术是由Steven henikoff博士团队开发的一种染色质图谱分析方法&#xff0c;基于Ulrich Laemmli博士的染色质免疫切割技术 (ChIC)&#xff0c;融合蛋白A与微球菌核酸酶 (pA-MNase)&#xff0c;选择性原位切割与抗体结合的染色质。在CUT&…

哪些因素影响转本复习效率?

一、精简资料 很多同学会搜集大量资料进行复习&#xff0c;在一轮轮复习之后你会很容易发现自己重复复习了大量内容和试题。 还有些同学将自己有限的精力和时间投入庞大的题海中&#xff0c;花费了大量的时间&#xff0c;但得到的提升不多。 同学们在脑海里一定要有清晰的认…

linux串口数据丢失--中断绑定CPU优化

问题现象 机器在户外测试时, 出现 轮速记 丢失的现象 小概率出现 50Hz丢失1~2帧极低概率出现 0.1~0.3秒内没有底盘数据 此问题导致slam定位漂, 需要优化处理. 验证与测试 问题1: 底盘串口 一个数据帧(head–data–crc) 被分片2~3报文 解决方法: 检测到head之后, 解析data…

MYSQL练题笔记-子查询-部门工资前三高的所有员工

这个系列的最后一个&#xff0c;也是所有的50题的第一个困难题&#xff0c;看着就有点吓人啧啧啧。 一、题目相关内容 1&#xff09;相关的表和题目 2&#xff09;帮助理解题目的示例&#xff0c;提供返回结果的格式 二、自己初步的理解 将每个部门分组&#xff0c;然后用ra…

搬运机器人行业分析:中国市场销量已达到6.3万台左右

近年来&#xff0c;随着我国人口红利的逐渐消失&#xff0c;企业用工成本不断上涨&#xff0c;各种工业机器人获得了广泛的应用。焊接、装配、切割、分拣、搬运等机器人的出现&#xff0c;不仅通过“机器换人”解放了企业和行业的生产力&#xff0c;更推动了产业发展由劳动密集…

Flink 有状态流式处理

传统批次处理方法 【1】持续收取数据&#xff08;kafka等&#xff09;&#xff0c;以window时间作为划分&#xff0c;划分一个一个的批次档案&#xff08;按照时间或者大小等&#xff09;&#xff1b; 【2】周期性执行批次运算&#xff08;Spark/Stom等&#xff09;&#xff1b…

MongoDB表的主键可以重复?!MongoDB的坑

MongoDB表的主键可以重复&#xff1f;&#xff01; 眼见为实&#xff1f; 碰到一个奇怪的现象&#xff0c; MongoDB的一个表居然有两个一样的_id值&#xff01; 再次提交时&#xff0c;是会报主键冲突的。那上图&#xff0c;为什么会有两个一样的_id呢&#xff1f; 将它们的…

C++刷题 -- 哈希表

C刷题 – 哈希表 文章目录 C刷题 -- 哈希表1.两数之和2.四数相加II3.三数之和&#xff08;重点&#xff09; 当我们需要查询一个元素是否出现过&#xff0c;或者一个元素是否在集合里的时候&#xff0c;就要第一时间想到哈希法; 1.两数之和 https://leetcode.cn/problems/two…

深入源码解析ArrayList:探秘Java动态数组的机制与性能

文章目录 一、 简介ArrayList1.1 介绍ArrayList的基本概念和作用1.2 与数组的区别和优势 二、 内部实现2.1 数据结构&#xff1a;动态数组2.2 添加元素&#xff1a;add()方法的实现原理2.3 扩容机制&#xff1a;ensureCapacity()方法的实现原理 三、 常见操作分析3.1 获取元素&…

0基础学习VR全景平台篇第127篇:什么是VR全景/720全景漫游?

“全景”作为一种表现宽阔视野的手法&#xff0c;在很久之前就得到了普遍的认同。北宋年间&#xff0c;由张择端绘制的《清明上河图》就是一幅著名的全景画。摄影术出现后&#xff0c;全景摄影也随之而生。 到今天&#xff0c;全景拍摄不再被专业摄影师所独享&#xff0c;广大…

C#的线程技术及操作(Thread类)

目录 一、线程基础 1.单线程 2.多线程 &#xff08;1&#xff09;多线程的缺点 &#xff08;2&#xff09;多线程的缺点 二、线程操作之Thread类 1. Thread类的相关方法和属性 &#xff08;1&#xff09;示例源码 &#xff08;2&#xff09;生成效果 2.创建线程Star…

代码随想录算法训练营 | day50 动态规划 123.买卖股票的最佳时机Ⅲ,188.买卖股票的最佳时机Ⅳ

刷题 123.买卖股票的最佳时机Ⅲ 题目链接 | 文章讲解 | 视频讲解 题目&#xff1a;给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔…