news 2026/5/1 7:25:00

算法题 数据流中的第 K 大元素

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法题 数据流中的第 K 大元素

数据流中的第 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 4 (数据流: [2,3,4,5,8]) kthLargest.add(5); // return 5 (数据流: [2,3,4,5,5,8]) kthLargest.add(10); // return 5 (数据流: [2,3,4,5,5,8,10]) kthLargest.add(9); // return 8 (数据流: [2,3,4,5,5,8,9,10]) kthLargest.add(4); // return 8 (数据流: [2,3,4,4,5,5,8,9,10])

算法思路

最小堆

核心思想:

  1. 维护一个大小为k的最小堆,堆顶元素就是第k大的元素
  2. 堆中始终保存数据流中最大的k个元素
  3. 当堆大小超过k时,移除堆顶(最小的元素)

为什么使用最小堆?

  • 最小堆的堆顶是堆中最小的元素
  • 如果堆中有k个元素,堆顶就是第k大的元素
  • 当有新元素加入时,如果新元素比堆顶大,它会替换掉堆顶,保持堆中始终是最大的k个元素

代码实现

方法一:最小堆

importjava.util.PriorityQueue;classKthLargest{privateintk;privatePriorityQueue<Integer>minHeap;/** * 初始化KthLargest对象 * * @param k 第k大的元素 * @param nums 初始数据流 */publicKthLargest(intk,int[]nums){this.k=k;// 创建最小堆(PriorityQueue默认是最小堆)this.minHeap=newPriorityQueue<>();// 将初始数组中的元素逐个加入堆for(intnum:nums){add(num);}}/** * 添加元素到数据流并返回第k大元素 * * @param val 要添加的元素 * @return 当前数据流中第k大的元素 */publicintadd(intval){// 将新元素加入堆minHeap.offer(val);// 如果堆大小超过k,移除堆顶(最小元素)if(minHeap.size()>k){minHeap.poll();}// 堆顶就是第k大的元素returnminHeap.peek();}}

算法分析

  • 时间复杂度
    • 初始化:O(N log k),其中N是初始数组长度
    • add操作:O(log k),堆操作的时间复杂度
  • 空间复杂度:O(k),堆中最多存储k个元素

算法过程

k=3, nums=[4,5,8,2]

初始化

  1. 添加4:堆=[4],大小=1≤3
  2. 添加5:堆=[4,5],大小=2≤3
  3. 添加8:堆=[4,5,8],大小=3≤3
  4. 添加2:堆=[4,5,8,2] → 大小>3 → 移除2 → 堆=[4,5,8]

堆状态:[4,5,8](最小堆,堆顶=4)

add操作

  1. add(3)

    • 堆=[4,5,8,3] → 大小>3 → 移除3 → 堆=[4,5,8]
    • 返回堆顶=4
  2. add(5)

    • 堆=[4,5,8,5] → 大小>3 → 移除4 → 堆=[5,5,8]
    • 返回堆顶=5
  3. add(10)

    • 堆=[5,5,8,10] → 大小>3 → 移除5 → 堆=[5,8,10]
    • 返回堆顶=5
  4. add(9)

    • 堆=[5,8,10,9] → 大小>3 → 移除5 → 堆=[8,9,10]
    • 返回堆顶=8
  5. add(4)

    • 堆=[8,9,10,4] → 大小>3 → 移除4 → 堆=[8,9,10]
    • 返回堆顶=8

最终数据流:[2,3,4,4,5,5,8,9,10]
最大的3个元素:[8,9,10]
第3大元素:8

测试用例

publicclassTestKthLargest{publicstaticvoidmain(String[]args){// 测试用例1:标准示例KthLargestkthLargest1=newKthLargest(3,newint[]{4,5,8,2});System.out.println("Test 1:");System.out.println("add(3): "+kthLargest1.add(3));// 4System.out.println("add(5): "+kthLargest1.add(5));// 5System.out.println("add(10): "+kthLargest1.add(10));// 5System.out.println("add(9): "+kthLargest1.add(9));// 8System.out.println("add(4): "+kthLargest1.add(4));// 8System.out.println();// 测试用例2:k=1(找最大值)KthLargestkthLargest2=newKthLargest(1,newint[]{});System.out.println("Test 2 (k=1):");System.out.println("add(1): "+kthLargest2.add(1));// 1System.out.println("add(3): "+kthLargest2.add(3));// 3System.out.println("add(2): "+kthLargest2.add(2));// 3System.out.println("add(4): "+kthLargest2.add(4));// 4System.out.println();// 测试用例3:k等于数组长度KthLargestkthLargest3=newKthLargest(2,newint[]{0});System.out.println("Test 3 (k=2):");System.out.println("add(-1): "+kthLargest3.add(-1));// -1System.out.println("add(1): "+kthLargest3.add(1));// 0System.out.println("add(-2): "+kthLargest3.add(-2));// -1System.out.println("add(-4): "+kthLargest3.add(-4));// -1System.out.println("add(3): "+kthLargest3.add(3));// 0System.out.println();// 测试用例4:大量重复元素KthLargestkthLargest4=newKthLargest(3,newint[]{5,5,5});System.out.println("Test 4:");System.out.println("add(5): "+kthLargest4.add(5));// 5System.out.println("add(5): "+kthLargest4.add(5));// 5System.out.println("add(10): "+kthLargest4.add(10));// 5System.out.println();// 测试用例5:负数KthLargestkthLargest5=newKthLargest(2,newint[]{-1,-2,-3});System.out.println("Test 5:");System.out.println("add(-4): "+kthLargest5.add(-4));// -2System.out.println("add(0): "+kthLargest5.add(0));// -1System.out.println("add(1): "+kthLargest5.add(1));// 0System.out.println();// 测试用例6:空初始数组KthLargestkthLargest6=newKthLargest(2,newint[]{});System.out.println("Test 6:");System.out.println("add(1): "+kthLargest6.add(1));// 1 (堆大小<2)System.out.println("add(2): "+kthLargest6.add(2));// 1 (堆=[1,2])System.out.println("add(3): "+kthLargest6.add(3));// 2 (堆=[2,3])System.out.println("add(0): "+kthLargest6.add(0));// 2 (堆=[2,3])}}

关键点

  1. 堆的大小

    • 始终维护堆大小为k
    • 超过k时移除最小元素(堆顶)
    • 确保堆中始终是最大的k个元素
  2. 为什么是最小堆而不是最大堆?

    • 最小堆能快速获取k个最大元素中的最小值(即第k大)
    • 最大堆需要存储所有元素,空间复杂度为O(N)
  3. 边界情况处理

    • 初始数组为空
    • k=1(找最大值)
    • k大于初始数组长度
    • 重复元素

常见问题

  1. 为什么不用最大堆?

    • 最大堆需要存储所有元素才能找到第k大,空间复杂度O(N)
    • 最小堆只需存储k个元素,空间效率更高
  2. 时间复杂度O(log k)?

    • 堆的插入和删除操作时间复杂度都是O(log size)
    • 堆的大小始终≤k,所以是O(log k)
  3. 找第k小元素?

    • 使用最大堆维护最小的k个元素
    • 堆顶就是第k小的元素
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 13:02:33

Solon AI MCP v3.7.3, v3.6.6 发布

Solon AI & MCP&#xff08;支持 LTS&#xff09; Solon AI & MCP &#xff0c;是 Solon 官方推出的 Java 智能体应用开发框架。旨在为 Java 开发者提供统一的接口抽象层&#xff0c;简化与 OpenAI、DeepSeek、QWen 等主流 AI 模型的集成流程&#xff0c;以及简化 Mcp…

作者头像 李华
网站建设 2026/5/1 6:10:02

OpenHarmony Flutter 分布式任务调度:跨设备负载均衡与资源优化方案

前言在开源鸿蒙&#xff08;OpenHarmony&#xff09;全场景分布式生态中&#xff0c;跨设备任务调度是实现多设备算力协同、资源高效利用的核心技术。传统单设备应用受限于硬件性能&#xff0c;无法高效处理高负载任务&#xff08;如 AI 计算、视频渲染、大数据分析&#xff09…

作者头像 李华
网站建设 2026/4/30 15:06:18

探索Qt下的UI皮肤生成器:多风格与编译那些事儿

Qt下UI皮肤生成器&#xff0c;好几套UI皮肤风格。 Qt5.6.1_MinGW的debug下需要将Pro里的PRECOMPILED_HEADER注释掉&#xff0c;在release下编译无问题&#xff1b; 源码&#xff1a; 使用Qt5.6.1_MinGW&#xff0c;Qt5.7.1_msvc编译通过。在Qt开发的世界里&#xff0c;UI皮肤生…

作者头像 李华
网站建设 2026/5/1 7:13:35

区间DP第3课:区间DP应用案例实践2

区间DP第3课&#xff1a;区间DP应用案例实践2 题目描述 有 NNN 个不同的正整数 x1x_1x1​, x2x_2x2​, …, xNx_NxN​ 排成一排&#xff0c;我们可以从左边或右边去掉连续的 iii (1≤i≤n)(1 \le i \le n)(1≤i≤n) 个数&#xff08;只能从两边删除数&#xff09;&#xff0c;…

作者头像 李华
网站建设 2026/5/1 7:12:45

哔哩下载姬DownKyi终极指南:3步上手B站视频批量下载与8K资源保存

哔哩下载姬DownKyi终极指南&#xff1a;3步上手B站视频批量下载与8K资源保存 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水…

作者头像 李华
网站建设 2026/4/18 10:06:04

Day 32 类的定义和方法

题目 1&#xff1a;定义圆(Circle)类要求 题目 2&#xff1a;定义长方形(Rectangle)类 题目 3&#xff1a;图形工厂 浙大疏锦行

作者头像 李华