100亿数据找出最大的1000个数字

面试题:解决的四种方法:

方法一:全排序法

1、最容易想到的方法是将数据全部排序。该方法并不高效,因为题目的目的是寻找出最大的10000个数即可,而排序却是将所有的元素都排序了,做了很多的无用功。

时间复杂度:O(NlogN),例如快排或归并排序;
空间复杂度:O(N)

方法二:小顶堆(局部淘汰法)

2、局部淘汰法。用一个容器保存前10000个数,然后将剩余的所有数字一一与容器内的最小数字相比,如果所有后续的元素都比容器内的10000个数还小,那么容器内这个10000个数就是最大10000个数。如果某一后续元素比容器内最小数字大,则删掉容器内最小元素,并将该元素插入容器,最后遍历完这1亿个数,得到的结果容器中保存的数即为最终结果了。此时的时间复杂度为O(n+m^2),其中m为容器的大小。

这个容器可以用(小顶堆)最小堆来实现。我们知道完全二叉树有几个非常重要的特性,就是假如该二叉树中总共有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读取比较频繁,对系统压力大。

时间复杂度:O((N-M)logM)
空间复杂度:O(M)

方法三:分治法,即Map-Reduce的思想

3、第三种方法是分治法,即大数据里最常用的MapReduce。

a、将100亿个数据分为1000个大分区,每个区1000万个数据

b、每个大分区再细分成100个小分区。总共就有1000*100=10万个分区

c、计算每个小分区上最大的1000个数。

为什么要找出每个分区上最大的1000个数?举个例子说明,全校高一有100个班,我想找出全校前10名的同学,很傻的办法就是,把高一100个班的同学成绩都取出来,作比较,这个比较数据量太大了。应该很容易想到,班里的第11名,不可能是全校的前10名。也就是说,不是班里的前10名,就不可能是全校的前10名。因此,只需要把每个班里的前10取出来,作比较就行了,这样比较的数据量就大大地减少了。我们要找的是100亿中的最大1000个数,所以每个分区中的第1001个数一定不可能是所有数据中的前1000个。

d、合并每个大分区细分出来的小分区。每个大分区有100个小分区,我们已经找出了每个小分区的前1000个数。将这100个分区的1000*100个数合并,找出每个大分区的前1000个数。

e、合并大分区。我们有1000个大分区,上一步已找出每个大分区的前1000个数。我们将这1000*1000个数合并,找出前1000.这1000个数就是所有数据中最大的1000个数。

(a、b、c为map阶段,d、e为reduce阶段)

方法四:hash法

4、Hash法。如果这1亿个书里面有很多重复的数,先通过Hash法,把这1亿个数字去重复,这样如果重复率很高的话,会减少很大的内存用量,从而缩小运算空间,然后通过分治法或最小堆法查找最大的10000个数。

对于海量数据处理,思路基本上是:必须分块处理,然后再合并起来。


100亿数据找出最大的1000个数字的4种方法相关推荐

  1. 100亿数据找出最大的1000个数字

    这是互联网领域一个比较经典的算法问题(top k),如何在巨大的数据中找出最大,或者访问量最高的前10个,前100个或者前1000个数据.比如在2亿用户记录中找出信用等级最高的,在上亿个搜索词汇中找出 ...

  2. JS实现找出数组中重复的数字的三种方法

    分享在JS中实现--找出数组中重复数字的方法的三种 法一. 排序比较法 先排序,再通过遍历比较,若相等,则添加到结果数组中,最后对结果数组进行去重,即可得到结果. function getSameNu ...

  3. 10亿数据找出前100大的数据

    方法1:利用堆排实现 取前m个数,建立一个小根堆.建堆的时间复杂度为O(mlogm) 顺序读取后边的元素,如果该元素比堆顶的元素小,直接丢弃.如果大于堆顶的元素则替换它,然后调整堆,最坏的情况是每一次 ...

  4. 10亿数据找出前100大的数据(网易大数据面试算法题)

    精华在评论区.... 当时去面试的时候现场现写,憋了将近一个小时,用递归实现了,估计问题很多,不是人家怎么可能不要我,哈哈哈,开个玩笑: 思路就是新建一个长度为100数组array1,把前100个元素 ...

  5. js判断数组中重复元素并找出_JavaScript判断数组重复内容的两种方法(推荐)

    前言 一般,我们可能会给数组去重,这个操作并不复杂,执行一个循环就是了.现在,我要做的是,判断数组中是否有重复的内容,如果有,返回 true 否则,返回 false. 思路 把数组变成字符串 循环原数 ...

  6. 100亿数据1万属性数据架构设计

    一分钟系列之<啥,又要为表增加一列属性?>分享了两种数据库属性扩展思路,被喷得厉害.第二天补充了一篇<这才是真正的表扩展方案>,分享了互联网大数据高并发情况下,数据库属性扩容的 ...

  7. 1万属性,100亿数据,每秒10万吞吐,架构如何设计?

    有一类业务场景,没有固定的schema存储,却有着海量的数据行数,架构上如何来实现这类业务的存储与检索呢?58最核心的数据"帖子"的架构实现技术细节,今天和大家聊一聊. 一.背景描 ...

  8. MySQL 亿级数据需求的优化思路(二),100亿数据,1万字段属性的秒级检索

    最近在研究亿级数据的时候,无意中看到了一个关于写58同城的文章 https://blog.csdn.net/admin1973/article/details/55251499?from=timeli ...

  9. python(dict字典相关知识以及小例子:生成一个列表,存放100个随机整数,找出出现次数最多的数字)

    一.什么是字典? #字典的使用 #子字典是一个容器类,可以用来存储数据 #列表存储数据特点:1.有序的 2.每一个都有一个索引,通过索引可以对数据进行查询,修改,删除#字典存储数据: key:valu ...

最新文章

  1. 美团某程序员爆料:绩效背c的都要签pip!网友:pip就是变相劝退!
  2. Linux 终端显示 Git 当前所在分支
  3. [BI项目记]-TFS Express备份和恢复
  4. SwiftSuspenders 1.6 浅出深入 深入 2
  5. 03 HttpServletRequest_HttpServletResponse
  6. android service 远程,android service(远程service) 知识点
  7. cmake导入so库_cmake编译.so库体积非常大,求解答
  8. Markdown中如何加入上标、下标?
  9. 圣诞节就这么过了.........
  10. Matlab Tricks(四)—— remove DC
  11. 崩坏学园2及大部分采用ETC1压缩格式的Unity3D游戏的拆包图处理
  12. 金字塔原理(Pyramid Principle)
  13. 编译原理实验五:编译器自动生成工具
  14. 思科网络综合实验(服务器,三层交换机,路由器)
  15. [论坛专贴]关于接口
  16. ioi2020集训队作业_IOI2020集训队作业
  17. 大数据内涵-“岂止于大”
  18. 可穿戴设备,朝“超人”迈进
  19. mysql的基础查阅
  20. 记录回家第一天的bug解决和心理过程

热门文章

  1. 利用位运算控制开关灯问题
  2. “轻松搞定CMake”系列之CMakeLists文件编写语法规则详解
  3. 【陆续更新】华港花园遭水灾之后的照片
  4. 盘点那些高大上的量化择时方法都有哪些?
  5. php获取数组的最后一个元素
  6. 2022-2028全球及中国用户威胁防护软件行业研究及十四五规划分析报告
  7. 游戏设计行业前景怎么样?学习3D建模需要多少钱?
  8. 从0开始写一个去水印小程序
  9. canvas生成姓氏头像,上传七牛后传给后端
  10. 微信定时发情话--python小程序