求 top k有哪些方法
大家好, 此文章分享求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)个, 分别与堆顶元素比较,此处构建的是最小堆
- 元素 > 堆顶元素: 替换堆顶元素, 调整堆 O(log k)
- 元素 < 堆顶元素, 该元素不可能是最后的K个元素,直接跳过
- 元素 == 堆顶元素, 该元素已存在堆中, 直接跳过
当遍历完剩余的(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有哪些方法相关推荐
- 堆实战(动态数据流求top k大元素,动态数据流求中位数)
动态数据集合中求top k大元素 第1大,第2大 ...第k大 k是这群体里最小的所以要建立个小顶堆 只需要维护一个大小为k的小顶堆 即可当来的元素(newCome)> 堆顶元素(smallTo ...
- queue emplace_c++ queue、deque、priority_queue/队列最大值/滑动窗口/top K
本篇文章介绍c++中关于队列的stl相关方法及概念介绍,例举3个经典算法题 一.queue 队列,常用方法: size_type size() bool empty() void push(value ...
- 精确查找top k和非精确查找top k
信息检索里面经典问题. 精确top K 检索及其加速办法 •方法一:快速计算余弦 • 方法二:堆排序法N中选K • 方法三:提前终止计算 精确top K检索加速方法一: 快速计算余弦 • 检索排序就是 ...
- c++求区间第k大数_数组中求第K大数的实现方法
问题:有一个大小为n的数组A[0,1,2,-,n-1],求其中第k大的数. 该问题是一个经典的问题,在<算法导论>中被作为单独的一节提出,而且其解决方法很好的利用了分治的思想,将时间复杂度 ...
- 用递归的方法求s = k! + n! / m!的值
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p142 7.1.2 上级实训内容 [实训内容5]求s = k! + n! / m!的值 #includ ...
- A*算法的认识与求第K短路模板
现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...
- 海量数据处理 - 10亿个数中找出最大的10000个数(top K)
海量数据处理 - 10亿个数中找出最大的10000个数(top K问题) 版权声明:本文为博主原创文章,未经博主允许不得转载 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望 ...
- 海量数据处理:如何从10亿个数中,找出最大的10000个数?(top K问题)
一.问题 有 10 亿个不重复的数字,内存中只能放进 1 万个数,怎么找到最大的 10 万个数字? 这道题的思路是,先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的) ...
- 程序员编程艺术:第三章续、Top K算法问题的实现
程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha. 致谢:微软100题实现组,狂想曲创作组. 时间:2011年05月08日 ...
最新文章
- 如何防止我的模型过拟合?这篇文章给出了6大必备方法
- android组合动画还原,Android - Fragment,View动画,组合动画,属性动画
- MyEclipse中JavaMail冲突问题
- boost::contract模块实现条件是否的测试程序
- FTP服务器架设详细图解
- Direct Training for Spiking Neural Networks: Faster, Larger, Better
- IT 人士工作中的十不要!
- JavaScript中charCodeAt函数
- 查询各分类中最大自增ID
- c#中关于结构体和字节数组转化
- 大白话聊聊Java并发面试问题之谈谈你对AQS的理解?
- git提交及打标签(tag)流程
- Day 45 Ansible批量管理
- Event Listener's Adapter Classes
- uni-app自定义搜索框-自定义按钮及搜索图标
- 【Laravel系列6.3】框架启动与服务容器源码
- 关于部分手机默认获取权限问题
- RFID应用安全+物联网安全标准
- hdu计算机网络实验,计算机网络实验报告(杭电).doc
- 字符串的Unicode