大家好, 此文章分享求top k有哪些方法

求 topk, 理解起来不难,就是很多元素中,找出前K个最大或者最小

假设我们求最大K元素

思路有以下几种:

1. 全局排序

所有元素加载到内存,来个全局排序,取前K个元素即可

最优算法复杂度: O(n * log n)

这个是最容易想到的

在没有时间和空间的复杂度要求,这样是没有问题。

2. 局部排序

我们只需要取前K个元素, 动用全局排序,显然是没有必要的

我们可以只排序TopK个元素,每拍一次序能确定前K个元素的一个,很自然会想到冒泡排序

采用冒泡排序K次就能得到TopK个元素了

算法复杂度: O( n * K)

3. 堆排序

局部排序中:采用冒泡每次排序的复杂度在 O(n), 不是局部排序的最优算法

局部排序得到:K个元素, 可以采用堆排序

首先

构建只有K个元素的最小堆或最大堆

  • 最小堆: 求topk 最大K元素
  • 最大堆: 求topk 最小K个元素

构建K个元素的堆,其算法复杂度: O(k log K)

其次,

遍历剩余元素 ( n - k)个, 分别与堆顶元素比较,此处构建的是最小堆

  1. 元素 > 堆顶元素: 替换堆顶元素, 调整堆  O(log k)
  2. 元素 < 堆顶元素, 该元素不可能是最后的K个元素,直接跳过
  3. 元素 == 堆顶元素, 该元素已存在堆中, 直接跳过

当遍历完剩余的(n - k) 个元素后, 堆中的K个元素就是topk

剩余元素遍历算法复杂度,最坏:O((n-k) * log k)

最终算法复杂度: O(n * log K), 优于冒牌排序的 O( n * K)

这个 O(n * log K) 一般就是大多数人能想到的最优方案了

其实还有更优的方案, 让我们来看最后一种方法

4.  随机选择

该方法的逻辑,受快速排序中得到partition的过程所启发

那么什么是partition?我简单介绍一下

partition操作: i = partition(array, 1, n) (  1 <= i <= n )

每次partition操作得到的 i 满足以下条件:

  • a[i]  左边的元素比 a[i] 大或者小
  • a[i]  右边的元素比 a[i] 小或者大

此处我们每次partition之后: 左边元素比a[i]大, 右边比a[i]小

  • 如果 i > k,  那么a[i]左边的元素都大于k,于是只递归a[1, i-1]里第k大的元素即可
  • 如果 i < k, 说明第k大的元素在a[i]的右边,于是只递归a[i+1, n]里第 k - i大的元素即可
  • 如果 i == K,第k大的元素就是当前i位置的, 数组前k个元素就是结果

该方法每次partition的复杂度,最大是: O( n)

每次partition都是分开独立的, 所有整个算法的时间复杂度才: O( n)

该算法是优于前面提到的所有算法的

扩展

如果数据量特别大, 我们如果计算topk?

求 top k有哪些方法相关推荐

  1. 堆实战(动态数据流求top k大元素,动态数据流求中位数)

    动态数据集合中求top k大元素 第1大,第2大 ...第k大 k是这群体里最小的所以要建立个小顶堆 只需要维护一个大小为k的小顶堆 即可当来的元素(newCome)> 堆顶元素(smallTo ...

  2. queue emplace_c++ queue、deque、priority_queue/队列最大值/滑动窗口/top K

    本篇文章介绍c++中关于队列的stl相关方法及概念介绍,例举3个经典算法题 一.queue 队列,常用方法: size_type size() bool empty() void push(value ...

  3. 精确查找top k和非精确查找top k

    信息检索里面经典问题. 精确top K 检索及其加速办法 •方法一:快速计算余弦 • 方法二:堆排序法N中选K • 方法三:提前终止计算 精确top K检索加速方法一: 快速计算余弦 • 检索排序就是 ...

  4. c++求区间第k大数_数组中求第K大数的实现方法

    问题:有一个大小为n的数组A[0,1,2,-,n-1],求其中第k大的数. 该问题是一个经典的问题,在<算法导论>中被作为单独的一节提出,而且其解决方法很好的利用了分治的思想,将时间复杂度 ...

  5. 用递归的方法求s = k! + n! / m!的值

    <程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p142 7.1.2 上级实训内容 [实训内容5]求s = k! + n! / m!的值 #includ ...

  6. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  7. 海量数据处理 - 10亿个数中找出最大的10000个数(top K)

    海量数据处理 - 10亿个数中找出最大的10000个数(top K问题) 版权声明:本文为博主原创文章,未经博主允许不得转载 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望 ...

  8. 海量数据处理:如何从10亿个数中,找出最大的10000个数?(top K问题)

    一.问题 有 10 亿个不重复的数字,内存中只能放进 1 万个数,怎么找到最大的 10 万个数字? 这道题的思路是,先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的) ...

  9. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

最新文章

  1. 如何防止我的模型过拟合?这篇文章给出了6大必备方法
  2. android组合动画还原,Android - Fragment,View动画,组合动画,属性动画
  3. MyEclipse中JavaMail冲突问题
  4. boost::contract模块实现条件是否的测试程序
  5. FTP服务器架设详细图解
  6. Direct Training for Spiking Neural Networks: Faster, Larger, Better
  7. IT 人士工作中的十不要!
  8. JavaScript中charCodeAt函数
  9. 查询各分类中最大自增ID
  10. c#中关于结构体和字节数组转化
  11. 大白话聊聊Java并发面试问题之谈谈你对AQS的理解?
  12. git提交及打标签(tag)流程
  13. Day 45 Ansible批量管理
  14. Event Listener's Adapter Classes
  15. uni-app自定义搜索框-自定义按钮及搜索图标
  16. 【Laravel系列6.3】框架启动与服务容器源码
  17. 关于部分手机默认获取权限问题
  18. RFID应用安全+物联网安全标准
  19. hdu计算机网络实验,计算机网络实验报告(杭电).doc
  20. 字符串的Unicode

热门文章

  1. 2级计算机证书有用吗,计算机2级证书有用吗
  2. 【转载】软件性能测试分析与调优实践之路-性能分析调优思想与调优技术总结
  3. Problem: 平板游戏
  4. python pip安装selenium_python+selenium安装
  5. 前端图片裁剪cropper.js
  6. node.js安装及环境变量配置
  7. DEADBEEF 是什么
  8. 物理学复试面试专业问题最全整理(魔鬼训练)
  9. 对于森林大火的肆虐,AI 能做些什么?
  10. 华为鸿蒙系统有多快?多家巨头实测比安卓快60%