• 经典面试题TOP k问题


    Top K 问题

    在大规模数据处理中,经常会遇到的一类问题:在海量数据中找出出现频率最好的前k个数,或者从海量数据中找出最大的前k个数,这类问题通常被称为top K问题

    1:如何在100亿数据中找到最大的1000个数

    最容易想到的就是将数据全排序,但是效率太低了,对于海量数据处理并不合适。

    方法一构建堆:

      用构建堆。(找1000个最大的数,构建最小堆)找1000个最小的数构建最大堆

    我们知道完全二叉树有几个非常重要的特性,就是假如该二叉树中总共有N个节点,那么该二叉树的深度就是log2N,

    对于小顶堆来说移动根元素到 底部或者移动底部元素到根部只需要log2N,相比N来说时间复杂度优化太多了(1亿的logN值是26-27的一个浮点数)

    具体思路:先从文件中取出1000个元素构建一个最小堆数组(O(log 1000)),然后对剩下的100亿-1000个数字m进行遍历,如果当前元素大于 最小堆的堆顶,

    就是K【0】元素,就用m取代k【0】,对新的数组从新构建小根堆。遍历结束,这个最小堆就是要找的数。

    时间复杂度:O((100亿 - 1000)log 1000) 就是O((N-M)logM), 空间复杂度M

    这个算法优点是性能尚可,空间复杂度低,IO读取比较频繁,对系统压力大。

    例题:  剑指offer最小的k个数

    这里还有堆排序

    方法二:分治法  即大数据里最常用的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法。

    如果这1亿个书里面有很多重复的数,先通过Hash法,把这1亿个数字去重复,这样如果重复率很高的话,会减少很大的内存用量,从而缩小运算空间,

    然后通过分治法或最小堆法查找最大的10000个数。

      

  • 相关阅读:
    添加鼠标右键菜单项(EditPlus为例)
    spring 定时器Quartz
    python脚本基础总结
    python2.7.9基础学习
    Vagrant+virtualBox+pycham+python环境的安装及配置
    python
    spring资料
    Java四种线程池的使用
    echarts学习网站
    hashmap两种遍历方法
  • 原文地址:https://www.cnblogs.com/xiaokang01/p/12562127.html
Copyright © 2020-2023  润新知