LeetCode 3885.设计事件管理器

给你一组初始事件列表,其中每个事件有一个唯一的 eventId 和一个 priority(优先级)。

实现 EventManager 类:

EventManager(int\[\]\[\] events) 使用给定事件初始化管理器,其中 eventsi = eventIdi, priorityi

void updatePriority(int eventId, int newPriority) 更新具有 id 为 eventId 的 活跃 事件的优先级为 newPriority。

int pollHighest() 移除并返回具有 最高优先级 的 活跃事件 的 eventId。如果有多个活动事件具有相同的优先级,则返回 eventId 最小的事件。如果没有活跃事件,则返回 -1。

如果一个事件没有被 pollHighest() 移除,则称其为 活跃事件。

示例 1:

输入:

"EventManager", "pollHighest", "updatePriority", "pollHighest", "pollHighest"

\[\[\[5, 7\], \[2, 7\], \[9, 4\]\]\], \[\], \[9, 7\], \[\], \[\]

输出:

null, 2, null, 5, 9

解释

EventManager eventManager = new EventManager(\[5,7, 2,7, 9,4]); // 使用三个事件初始化管理器

eventManager.pollHighest(); // 两个事件 5 和 2 的优先级均为 7,因此返回 id 最小的事件 2

eventManager.updatePriority(9, 7); // 将事件 9 的优先级更新为 7

eventManager.pollHighest(); // 剩下的优先级最高的事件是 5 和 9,返回 5

eventManager.pollHighest(); // 返回 9

示例 2:

输入:

"EventManager", "pollHighest", "pollHighest", "pollHighest"

\[\[\[4, 1\], \[7, 2\]\]\], \[\], \[\], \[\]

输出:

null, 7, 4, -1

解释

EventManager eventManager = new EventManager(\[4,1, 7,2]); // 使用两个事件初始化管理器

eventManager.pollHighest(); // 返回 7

eventManager.pollHighest(); // 返回 4

eventManager.pollHighest(); // 没有剩余事件,返回 -1

提示:

1 <= events.length <= 105^55

eventsi = eventId, priority

1 <= eventId <= 109^99

1 <= priority <= 109^99

events 中的所有 eventId 值都是 唯一的 。

1 <= newPriority <= 109^99

对每次调用 updatePriority,eventId 都指向一个 活跃事件。

对 updatePriority 和 pollHighest 的总调用次数最多为 105^55 次。

懒删除堆,我们可以维护一个优先级和事件id的最大堆,以及一个事件Id到优先级的哈希表。每次updatePriority时,先修改哈希表,然后不删除堆中当前事件id的优先级,而是插入一个新的正确节点进堆;每次pollHighest时,检查当前堆顶事件id的优先级是否是哈希表中存放的优先级,如果是,就找到了优先级最高的事件,否则堆顶就是失效的事件:

cpp 复制代码
class EventManager {
public:
    EventManager(vector<vector<int>>& events) {
        for (vector<int> &event : events) {
            eventToPriority[event[0]] = event[1];
            heap.push_back({event[1], -event[0]});
        }

        make_heap(heap.begin(), heap.end());
    }
    
    void updatePriority(int eventId, int newPriority) {
        eventToPriority[eventId] = newPriority;
        
        heap.push_back({newPriority, -eventId});
        push_heap(heap.begin(), heap.end());
    }
    
    int pollHighest() {
        while (!heap.empty() && 
          (eventToPriority.find(-heap[0][1]) == eventToPriority.end() || heap[0][0] != eventToPriority[-heap[0][1]])) {
            pop_heap(heap.begin(), heap.end());
            heap.pop_back();
        }

        if (heap.empty()) {
            return -1;
        }

        int ans = -heap[0][1];
        pop_heap(heap.begin(), heap.end());
        heap.pop_back();

        eventToPriority.erase(ans);

        return ans;
    }

private:
    unordered_map<int, int> eventToPriority;
    vector<vector<int>> heap;
};

/**
 * Your EventManager object will be instantiated and called as such:
 * EventManager* obj = new EventManager(events);
 * obj->updatePriority(eventId,newPriority);
 * int param_2 = obj->pollHighest();
 */

时间复杂度:

初始化:O(n),其中 n 是 events 的长度。

updatePriority:O(log(n+q)),其中 q 是 updatePriority 的调用次数。

pollHighest:均摊 O(log(n+q))。每个元素至多入堆出堆各一次。

空间复杂度:O(n+q)。

相关推荐
枫叶林FYL42 分钟前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕1 小时前
滑动窗口算法实战指南
python·算法
DisonTangor1 小时前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手
明月_清风2 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣2 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338373 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J3 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动
血小板要健康3 小时前
链表 阶段算法总结
java·数据结构·笔记·算法·leetcode·链表
a187927218313 小时前
【算法】回溯算法(三):三记重锤与 N 皇后——记忆化、状态设计与三层漏斗
算法·leetcode·go·剪枝·回溯·n皇后·算法讲解
HugoStudio_SWAN5 小时前
洛谷 P1420 / P1179 / B4262 最长连号、数字统计与词频统计——统计的三种面孔
c++·学习·程序人生·算法