海量数据TOP K问题

含义

在海量数据找出频率最高的前k个数,或从海量数据中找出最大的前k个数,

1.利用堆找出最大的K个数
  首先,先理解下用堆找出最大的K个数的常用解法,例如问题是“从M(M <= 10000)个数中找出最大的K个数”

  • 利用最大堆 (适合于M规模不大的场景)
      建立一个N=M大小的大顶堆,然后输出根节点之后,将根节点删除,然后再将剩余的元素调整成大顶堆;依次重复K次这个过程,最终就找出了K个最大的数。这实质上就是堆排序的过程。这种方法的时间复杂度为O(K *logM)

  • 利用最小堆(适用于小内存,大数据)
      这是最常用的一种方式,首先建立一个N=K大小的小顶堆,这K个元素可以为M中元素中的任意K个;那么对于剩下的M-K个元素,我们逐个与根节点进行对比。
      
    如果当前元素大于根节点的元素的话,就将当前的元素与根节点的元素进行交换,然后将堆再次进行进行调整成最小堆,重复这个过程,直到比较完剩下的M-K个元素;那么最终的小顶堆对应的K个数,必然是M个数中的最大的K个数。这种方法的时间复杂度为O(M*logK)。

方法2相对方法1而言,所需要的内存空间更小了,方法1建立的堆需要M个元素对应的内存空间,而方法2建立的堆只需要K个元素对应的内存空间,所以在对内存空间有严格要求的情况下,采用方法2会更加好一些。

2.海量数据中找出最大的K个数

  • 分治思想
      对于1而言,M这个指不能很大;如果M很大的话(比如M = 40亿),就不能直接使用排序来找了。对于这种情况,一般是利用“hash映射+堆”的过程,这里的堆是指的方法2,具体如下:
      
    将40亿个数分成若干小的部分(分成多少部分要看题目对内从空间大小的限制),其中N为分成的部分数;然后对于每个小的部分,如果内存可以一次性读取的话,则利用堆采用方法2,选取每个小部分数据中的TOPK个元素,一共NK个元素,然后继续利用堆,采用方法2从这NK个元素种找出最大的K个元素。

  • 全排序 (一般不用,内存不够)

  • 局部淘汰法
    使用一个长度为K的数组,保存钱K个数据,排序,剩下的M-K个数和数组中的数比较,淘汰最小值。O(n+m^2)

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

  • 最小堆法
    见 1.2

总结:
top K问题很适合采用MapReduce框架解决,用户只需编写一个Map函数和两个Reduce 函数,然后提交到Hadoop(采用Mapchain和Reducechain)上即可解决该问题。具体而言,就是首先根据数据值或者把数据hash(MD5)后的值按照范围划分到不同的机器上,最好可以让数据划分后一次读入内存,这样不同的机器负责处理不同的数值范围,实际上就是Map。得到结果后,各个机器只需拿出各自出现次数最多的前N个数据,然后汇总,选出所有的数据中出现次数最多的前N个数据,这实际上就是Reduce过程。对于Map函数,采用Hash算法,将Hash值相同的数据交给同一个Reduce task;对于第一个Reduce函数,采用HashMap统计出每个词出现的频率,对于第二个Reduce 函数,统计所有Reduce task,输出数据中的top K即可。

3.找出100亿个URL中重复的URL

(1)对于这类问题,通常采用的的算法思想是“hash映射+哈希表”;大体而言,将100亿个URL利用哈希函数分成N个部分,每个部分用哈希表进行统计次数,最终找到所有重复的URL。

(2)利用字典树。

4.找出20亿个数中出现次数最多的数

解决这类问题的想和3中的法(1)类似。

5.找出40亿个非负整数中出现0次、1次…N次的数

一般找出非负整数中的出现多少次的数,都是利用BItMap

三、延申
处理海量数据问题方法:

分治/hash映射 + hash统计 + 堆/快速/归并排序;
双层桶划分;
Bloom filter/Bitmap;
Trie树/数据库/倒排索引;
外排序;
分布式处理之Hadoop/Mapreduce。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值