力扣-1353. 最多可以参加的会议数目

news/2024/9/27 15:21:31

1.题目介绍

题目地址(1353. 最多可以参加的会议数目 - 力扣(LeetCode))

https://leetcode.cn/problems/maximum-number-of-events-that-can-be-attended/

题目描述

给你一个数组 events,其中 events[i] = [startDayi, endDayi] ,表示会议 i 开始于 startDayi ,结束于 endDayi 。

你可以在满足 startDayi <= d <= endDayi 中的任意一天 d 参加会议 i 。在任意一天 d 中只能参加一场会议。

请你返回你可以参加的 最大 会议数目。

 

示例 1:

输入:events = [[1,2],[2,3],[3,4]]
输出:3
解释:你可以参加所有的三个会议。
安排会议的一种方案如上图。
第 1 天参加第一个会议。
第 2 天参加第二个会议。
第 3 天参加第三个会议。

示例 2:

输入:events= [[1,2],[2,3],[3,4],[1,2]]
输出:4

 

提示:​​​​​​

  • 1 <= events.length <= 105
  • events[i].length == 2
  • 1 <= startDayi <= endDayi <= 105

2.题解

2.1 贪心算法 + 优先级队列(小根堆)

思路

这里我们思考最优贪心策略:
从左到右遍历时间点i,某会议x在满足起始时间startTime大于i(必要条件,否则无法参加),同时结束时间endTime是最早的(因为它结束时间最早,所以相比那些结束时间晚的更容易被淘汰,故优先选择),每次都选择这样的会议参加或者该时间点没有会议参加,局部最优达成全局最优。

那我们就要考虑进行实现了,首先要维护当前时间点i,可以参加的所有会议(并不是所有会议都开始了)
我们并不想维护一个长度为max_TimeEnd的vector数组,并记录其中所有可以参与的会议(这样我们要遍历max_TimeEnd次数组,而且还要花费非常多的额外空间进行维护)
我们选择使用优先级队列进行动态维护,当当前会议开始后,就将该会议加入到队列中;当当前会议到达结束时间后/我们选择参与了该会议,我们将该会议从队列去除。

还有一个问题,我们该如何根据当前时间i,快速判断有哪些会议开始,又有哪些会议结束呢?
如果使用原来的数组,我们每次选择都要从头到尾遍历一遍并进行判断,这十分的耗费时间,
所以我们选择使用一个哈希表来维护:开始时间--结束时间的映射(这里一个开始时间可能对应多个结束时间,比如像多个会议都是时间i开始,但结束时间不一样,所以第二个参数是vector)
当我们得知当前时间后,就可以用mp.count(i)判断是否有当前日期i开始的会议,并根据映射将mp[i]中存储的结束时间加到优先级队列中,这样就维护了进队操作。

这里我们使用一个基于小根堆的优先级队列,队列存储的是各个会议的结束时间,这样就可以在选择会议时让结束时间早的会议优先出队!
同时对于结束时间 < 当前时间的会议, 说明其已经结束了,不可能再进行选择, 我们也要将其出队。 这样就维护了出队操作

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:int maxEvents(vector<vector<int>>& events) {unordered_map<int, vector<int>> mp;int cnt = 0;int max_day = 0; // 用于记录所有活动中最晚的结束时间,确定遍历结束点for(vector<int> event : events){// 记录开始时间和结束时间的映射,便于下文我们进行寻找mp[event[0]].push_back(event[1]);max_day = max(max_day, event[1]);}// 自底向上,将最早(小)结束的排在前面,所以greater(父节点 > 子节点的值就交换,将大的值沉底)priority_queue<int, vector<int>, greater<int>> q; // 从左到右遍历每一天,看每一天是否有会议可以参加for(int i = 0; i <= max_day; i++){// 如果有今天开始的会议,加入优先级队列if(mp.count(i)){for(int endTime : mp[i]){q.push(endTime);}   }// 去除在今天i已经结束的队列成员while(!q.empty() && q.top() < i){q.pop();}// 选择一个结束最早的会议参加if(!q.empty()){cnt++;q.pop();}}return cnt;}
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(n)\)
  • 空间复杂度:\(O(n)\)

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

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

相关文章

QLineEdit限定只能输入整数

QLineEdit限定输入整数时遇到的问题 问题 QValidator常常用于判断数据的合法性,QLineEdit,QSpinBox,QComboBox中经常使用该类。 QLineEdit要限制输入整数,那么添加语句lineEdit->setValidator(new QIntValidator(100, 1000, this)),理论上可以实现限定只能输入100-1000…

Sql注入之WAF绕过

WAF 拦截原理 WAF 绕过的思路就是让 WAF 的检测规则,识别不到你所输入的敏感字符,利用上述所介绍的知识点,灵活结合各种方法,从而可以增加绕过 WAF 的可能性.1. 关键词大小写绕过 有的WAF因为规则设计的问题,只匹配纯大写或纯小写的字符,对字符大小写混写直接无视,这时,…

【持续更新】重要FLIP总结

FLIP-27: Refactor Source Interface 流批一体API 1、解耦SplitEnumerator与SplitReader SplitEnumerator:发现并分配splits(比如files/kafka_partitions) SourceReader:从splits里实际读取数据 这样就使不同的splits分配策略与读取动作解耦,可分别封装成两个组件,Source…

Java-HashMap中put源码解读

1.背景Map类型 优点 缺点 线程安全性HashMap 1. 查询、插入、删除操作的时间复杂度为O(1)。2. 允许键和值为null。 1. 无序,不保证迭代顺序。2. 不是线程安全的。 LinkedHashMap 1. 保留插入顺序或访问顺序。2. 与HashMap性能相似。 1. 内存开销较高,因为维护了一个双向链表。…

大模型显存计算

大模型微调需要多少GPU显存?如:微调 1B 模型,16bit = 2byte全量微调显存占用分为:model weight(参数本身):10亿(bit) = 20亿(byte)约等于2GB训练模型时,通过一系列反向传播的方法,来更新模型参数,涉及以下gradient​和optimizer states​参数。不断计算梯度,以更…

一图看懂编码,加密,令牌化的不同之处

一图看懂编码,加密,令牌化的不同之处

解决HBuilder X识别不了魅族手机的问题

似乎魅族手机有点特别,别的手机识别没事,但是到了魅族手机就是识别不了,下面上处理方案 这里假设你的调试已经打开的情况下, 找到目录C:\Users\tutu-qiuxie\Downloads\HBuilderX\plugins\launcher-tools\tools\adbs先把软件关闭, 打开HbuilderX后,记得手机上弹出的是否允…

[模式识别复习笔记] 第5章 贝叶斯分类器

1. 贝叶斯分类器 1.1 贝叶斯公式 假设有一个试验的样本空间为 \(S\),记 \(B_1, B_2, \ldots, B_c\) 为 \(S\) 的一个划分,\(A\) 为试验的条件,且 \(P(A) \not = 0\),则: \[P(B_i | A) = \frac{P(B_i)P(A|B_i)}{P(A)} = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^{c}P(B_j)P(A|B_j…