100亿数据找出最大的1000个数字
来源:互联网 发布:a类网络ip地址 编辑:程序博客网 时间:2024/05/16 18:54
这是互联网领域一个比较经典的算法问题(top k),如何在巨大的数据中找出最大,或者访问量最高的前10个,前100个或者前1000个数据。比如在2亿用户记录中找出信用等级最高的,在上亿个搜索词汇中找出被搜索次数最高的10个关键字。前提是数据存储在文件中
一般遇到这个问题,第一反应会想到排序,但是稍微对内存有点了解的人立刻都会否定这个答案,大量的数据导入内存且不说内存够不够,就算足够服务器上其他的服务都不需要内存了吗?那么接下来的思路就是,如果不允许全部导入内存,还要找出最大的1000个数字,那就要用到外部排序(选择)的算法了。
解决的思路有下面几个:
1.采用小顶堆算法,我们知道完全二叉树有几个非常重要的特性,就是假如该二叉树中总共有N个节点,那么该二叉树的深度就是log2N,对于小顶堆来说移动根元素到 底部或者移动底部元素到根部只需要log2N,相比N来说时间复杂度优化太多了(1亿的logN值是26-27的一个浮点数)。基本的思路就是先从文件中取出1000个元素构建一个小顶堆数组k,然后依次对剩下的100亿-1000个数字进行遍历m,如果m大于小顶堆的根元素,即k[0],那么用m取代k[0],对新的数组进行重新构建组成一个新的小顶堆。这个算法的时间复杂度是O((100亿-1000)log(1000)),即O((N-M)logM),空间复杂度是M
这个算法优点是性能尚可,空间复杂度低,IO读取比较频繁,对系统压力大。
2.采用分区法,将100亿个数据分成1000个分区,每个分区上1000万个数据,在每个分区上上再细分成100个分区,即总共分成1000*100个分区,然后启动多线程进行处理,各个分区上采用小顶堆算法取出最大的1000个数据,分层进行合并然后重新计算不同层上的最大1000个数,最终递归到最上层。但linux系统上一个进程能启动的默认线程数是1024个,所以要么调整最大线程数,要么在线程调用处做一些处理,比如一个线程完成一个分区之后再去处理相邻的分区,或者在分区的时候把所有的分区数目限制在1024之内。这个算法切合了map-reduce的思想,利用了多线程和多处理器的优势,减少了多余的比较和IO读取,性能比第一种会更好但算法更复杂一点,要考虑的情况也更多。
- 100亿数据找出最大的1000个数字
- 100亿个数字中找出最大的10个
- 从100亿个整数中找出最大/最小的1000个整数
- 给定1亿int,找出最大的100个
- 满大街都是这种烂题目------从100亿个整数中找出最大的1000个整数
- 找出N个数据中的最大的K个数据---堆排序
- 【数据结构】找出N个数据中最大的前k个数据(利用堆排序)
- 【数据结构】找出N个数据中最大的前k个数据(利用堆排序)
- 编写程序,用户输入10个数字,找出最大的,和最小的
- n个数里面找出最大的m个数字(快排思想)
- 找出100个50位数之和的前十位数字。
- 上亿个数据保存在硬盘中,找出最大的N个。
- 从大量的数据中找出若干个最大或者最小的数据
- 找出最大的5个值。
- 找出第一个重复的数字
- 10亿数据中取最大的100个数据
- 从2.5亿个数字里面找出不重复的数字的个数
- 从2.5亿个数字里面找出不重复的数字的个数
- Linux命令基础34-如何在一个终端一次运行多个命令
- 图像处理行业专业级类库OpenCV
- uCOS-ii 如何获取最高优先级的Task
- 413. Arithmetic Slices Add to List
- oracle创建数据库和删除数据库
- 100亿数据找出最大的1000个数字
- h.264/AVC的结构 NAL结构
- lnmp搭建(三)PHP安装及配置
- [HEOI2015]兔子与樱花
- 最短路问题
- linux 手动设置ip ..
- Android自定义控件--ProgressButton
- 全球勒索病毒爆发撞上比特币 ETF 重审,是巧合还是阴谋?
- C中结构体是否能用=运算符直接赋值的问题