当前位置: 首页 > news >正文

【Java】TOP-K问题

TOP-K问题

  • 题目
  • 算法的思路详解
    • 整体排序法
    • 整体建立小顶堆法
    • 大小为 K 的大顶堆法
  • code
    • 整体排序法
    • 整体建立小顶堆法
    • 大小为K的大顶堆法
    • 三种方法对比

题目

https://leetcode.cn/problems/smallest-k-lcci/description/

算法的思路详解

整体排序法

核心思路
既然要找最小的前 K 个元素,那就干脆把所有元素排好序,然后直接取前 K 个。

执行步骤

  1. 将整个数组从小到大排序
  2. 取出排序后数组的前 K 个元素

优点:代码最简单,思路最直接
缺点:做了很多"无用功"——我们只需要前 K 小,却把整个数组都排好了

整体建立小顶堆法

核心思路
用小顶堆的特性——堆顶永远是最小值。把所有元素放入堆中,然后依次弹出堆顶,弹出来的就是从小到大的顺序。

执行步骤

  1. 把所有 N 个元素放入一个小顶堆(建堆 O(N))
  2. 从堆顶弹出元素,弹出来的就是当前最小值
  3. 重复弹出 K 次,得到前 K 小的元素

优点:比排序法稍快(建堆 O(N) vs 排序 O(N log N))
缺点:仍然需要存储全部 N 个元素

大小为 K 的大顶堆法

核心思路
维护一个"门槛"——只关心前 K 小的元素,大于门槛的统统不要。用大顶堆来记录当前找到的 K 个候选,堆顶是这 K 个里面最大的(也就是当前的"门槛")。

执行步骤

  1. 先用前 K 个元素建一个大顶堆(堆顶是这 K 个中最大的)
  2. 遍历剩下的 N-K 个元素:
    • 如果当前元素小于堆顶(门槛),说明它应该进入前 K 小
    • 把堆顶(最大的那个)踢出去,把当前元素加进来
  3. 遍历结束后,堆里剩下的就是前 K 小的元素

为什么用大顶堆?
因为我们要快速知道当前 K 个候选中的最大值是谁,新来的只要比它小,就能替换掉它。

优点:内存占用极小(只存 K 个元素),适合海量数据(比如 10 亿个数找前 100 小)
缺点:实现稍复杂

code

整体排序法

// 1. 整体排序法publicstaticList<Integer>topKBySorting(int[]arr,intk){if(arr==null||arr.length==0||k<=0)returnnewArrayList<>();int[]copy=Arrays.copyOf(arr,arr.length);Arrays.sort(copy);List<Integer>result=newArrayList<>();for(inti=0;i<k&&i<copy.length;i++){result.add(copy[i]);}returnresult;}

整体建立小顶堆法

// 2. 整体建立小顶堆法(把所有元素放入小顶堆,再弹出前K个)publicint[]smallestK(int[]arr,intk){int[]result=newint[k];if(arr==null||arr.length==0||k<=0)returnresult;PriorityQueue<Integer>heap=newPriorityQueue<>();// 小顶堆for(intnum:arr){heap.offer(num);}for(inti=0;i<k;i++){result[i]=(heap.poll());}returnresult;}

大小为K的大顶堆法

// 3. 大小为K的大顶堆法(推荐,适合大数据量)classIntCmpimplementsComparator<Integer>{@Overridepublicintcompare(Integero1,Integero2){returno2.compareTo(o1);}}classSolution{publicint[]smallestK(int[]arr,intk){int[]result=newint[k];if(arr==null||arr.length==0||k<=0)returnresult;PriorityQueue<Integer>heap=newPriorityQueue<>(newIntCmp());// 大顶堆for(inti=0;i<k;i++){heap.offer(arr[i]);}for(intj=k;j<arr.length;j++){if(heap.peek()>arr[j]){heap.poll();heap.offer(arr[j]);}}for(intl=0;l<k;l++){result[l]=(heap.poll());}returnresult;}}

三种方法对比

方法思路
整体排序全部排好序,再取前 K 个
整体小顶堆所有元素进堆,再弹出 K 次
大小为 K 的大顶堆维持一个 K 大小的"候选池",池里最大的就是门槛
方法时间复杂度空间复杂度说明
整体排序O(N log N)O(N) 或 O(log N)(原地排序)简单直接,但不需要全部排序
整体小顶堆O(N + K log N)O(N)建立堆 O(N),弹出 K 次 O(K log N)
大小为 K 的大顶堆O(N log K)O(K)最适合流式/海量数据,内存占用最小
http://www.jsqmd.com/news/604584/

相关文章:

  • 实战演练:用快马AI快速打造集成终端功能的服务器监控与部署面板
  • 当 AI 开始一本正经地胡说八道:DeepSeek 幻觉率 14%给技术人的警示
  • 面向嘈杂语音的对话建模新挑战
  • 手把手教你用Python实现TOTP动态验证码生成器(附完整代码)
  • AI同事抑郁症诊断报告:大模型存在主义危机爆发
  • 牧苏苏传 辣个男人回来了 4/6
  • 2026最权威的五大降AI率平台实际效果
  • 焊接仓储笼、仓储箱、周转箱、网格铁框、金属周转箱、仓储货架网、仓储货架网片厂家电话 - 企业推荐官【官方】
  • 我用Hermes Agent的经历——对比OpenClaw
  • 硕博生一定要尽快掌握用AI绘图啊!!
  • 电-气综合能源系统能量与备用调度:基于Wasserstein距离和CVaR条件风险价值的分布鲁...
  • 快速降AI率哪款工具最值得试?按需求推荐 - 我要发一区
  • Rust所有权与借用规则深度解析:从踩坑到理解
  • 面向对象高级(多态)
  • 想找国内知名光变UV变色纱线生产厂家?这3家值得关注 - 企业推荐官【官方】
  • 靠谱的厚板吸塑实力厂家 - 企业推荐官【官方】
  • 手把手教你用R-Studio恢复误删文件:从下载到恢复的保姆级避坑指南
  • 告别数据映射困惑:手把手教你配置ADRV9009的JESD204B接口(以BR3109为例)
  • 鼎捷T100程序开发实战:从核心类型到高效开发全解析
  • Windows系统性能优化全景指南:从诊断到长效管理的科学路径
  • 【OpenCode】opencode配置minimax2.7【day2】
  • 语文_中考_古诗词
  • 双编码器在UR5机器人零力拖动中的实现与优化
  • YALMIP求解器设置避坑指南:从`verbose`到`relax`,这些参数设置错了可能让你白算一整天
  • 终极Windows右键菜单优化指南:如何用ContextMenuManager快速清理杂乱菜单
  • CVPR/ICCV跟踪新趋势解读:对比学习如何让MOT模型学会“认人”?
  • 夜光荧光发光纱线生产厂家怎么选?认准正规靠谱源头不踩坑 - 企业推荐官【官方】
  • 从游戏AI到机器人:PPO算法在5个真实项目中的应用实战解析
  • 基于多时间尺度的灵活性资源优化配置 关键词:多时间尺度;模型预测控制;日内滚动优化; 1. 程序
  • 三大国际正规温变变色纱线供应商推荐 - 企业推荐官【官方】