算法日常・每日刷题--<优先级队列>2

LCR 059. 数据流中的第 K 大元素 - 力扣(LeetCode)LCR 059. 数据流中的第 K 大元素 - 设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。请实现 KthLargest 类: * KthLargest(int k, int\[\] nums) 使用整数 k 和整数流 nums 初始化对象。 * int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。 示例:输入:"KthLargest", "add", "add", "add", "add", "add"\[3, \[4, 5, 8, 2], 3, 5, 10, 9, 4]输出:null, 4, 5, 5, 8, 8解释:KthLargest kthLargest = new KthLargest(3, 4, 5, 8, 2);kthLargest.add(3); // return 4kthLargest.add(5); // return 5kthLargest.add(10); // return 5kthLargest.add(9); // return 8kthLargest.add(4); // return 8 提示: * 1 <= k <= 104 * 0 <= nums.length <= 104 * -104 <= numsi <= 104 * -104 <= val <= 104 * 最多调用 add 方法 104 次 * 题目数据保证,在查找第 k 大元素时,数组中至少有 k 个元素 注意:本题与主站 703 题相同: https://leetcode.cn/problems/kth-largest-element-in-a-stream/ https://leetcode.cn/problems/kth-largest-element-in-a-stream/https://leetcode.cn/problems/jBjn9C/

一、题目描述

题目要求

设计一个可以持续接收数据流、快速返回第 K 大元素 的类 KthLargest,注意定义:将所有数字降序排序后,位于第 k 个位置的数,允许存在重复数字。 需要实现两个核心方法:

  1. 构造函数 KthLargest(int k, vector<int>& nums):给定 k 和初始数字流完成初始化;
  2. int add(int val):新增一个数字到数据流,返回当前全局第 k 大的值。

示例

输入:k=3,初始数组 [4,5,8,2] 依次调用 add(3)、add(5)、add(10)、add(9)、add(4) 输出:4,5,5,8,8 解释:

  • 初始数据流:[4,5,8,2],前 3 大数字 [4,5,8],第 3 大为 4;
  • 添加 3 后,前 3 大不变,返回 4;
  • 添加 5 后,前 3 大 [5,5,8],返回 5;
  • 添加 10 后,前 3 大 [5,8,10],返回 5;
  • 添加 9 后,前 3 大 [8,9,10],返回 8;
  • 添加 4 后,前 3 大不变,返回 8。

二,最优解法:固定容量小根堆(最小堆)

核心原理

我们只需要全局最大的 k 个数字,不需要存储全部数据:

  1. 使用小根堆,堆内最多保存 k 个元素;
  2. 堆的特性:堆顶是堆中最小值
  3. 堆内存放当前前 k 大数字,堆顶天然就是全局第 k 大元素。

执行流程

  1. 初始化阶段:遍历所有初始数字,逐个入堆;若堆长度超过 k,弹出堆顶最小值(该数不属于前 k 大);
  2. add 新增数字:
    • 将新数字压入堆;
    • 若堆大小 > k,弹出堆顶最小元素;
    • 直接返回堆顶,即为当前第 k 大值。

为什么不用大根堆?

如果使用大根堆,会存储全部数据流,空间复杂度 O(n);且每次取第 k 大需要遍历堆,效率低下。小根堆仅存 k 个元素,空间、时间双重最优。

cpp 复制代码
class KthLargest {
    priority_queue<int ,vector<int>,greater<int>>heap;
    int _k; 
public:
    KthLargest(int k, vector<int>& nums) {
        _k=k;
        for(auto e:nums)
        {
            heap.push(e);
            if(heap.size()>_k)
            heap.pop();
        }
    }
    
    int add(int val) {
        heap.push(val);
        if(heap.size()>_k)
        heap.pop();
        return heap.top();

    }
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */
相关推荐
YaraMemo38 分钟前
元启发式算法框架
人工智能·算法·5g·信息与通信·启发式算法·信号处理
weixin_307779131 小时前
一维无粘 Burgers 方程的激波形成问题:MacCormack 格式求解
c++·算法·matlab
HugoStudio_SWAN1 小时前
洛谷 B4500 / B4449 / B3843 凯撒密码、密码强度与密码合规——加密与安全的三道门
c++·学习·程序人生·算法·安全
枫叶林FYL2 小时前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕3 小时前
滑动窗口算法实战指南
python·算法
DisonTangor3 小时前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手
明月_清风4 小时前
从二叉树到 B+ 树:一文搞懂工程中「树」的演化之道
数据结构·算法·go
渡我白衣4 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
hetao17338374 小时前
2026-09-01~09-04 hetao1733837 的刷题记录
c++·算法
Evand J5 小时前
【MATLAB例程,图像滤波5】 反谐波均值滑动窗口滤波(CHMF)图像降噪与质量评价,附代码下载链接
图像处理·算法·计算机视觉·matlab·均值算法·滑动窗口滤波·均值滑动