在面试中常常问到:在搜索引擎中,统计搜索最热门的10个查询词;在歌曲库中统计下载最高的前10首歌等。在海量数据中找出最大的前k个数,这类问题统称为top K问题。
1. 分治+Trie树/hash+小顶堆
即先将数据集按照Hash方法分解成多个小数据集,然后使用Trie树活着Hash统计每个小数据集中的query词频,之后用小顶堆求出每个数据集中出现频率最高的前K个数,最后在所有top K中求出最终的top K。
一、小顶堆
小顶堆(min-heap)有个重要的性质——每个结点的值均不大于其左右孩子结点的值,则堆顶元素即为整个堆的最小值。
小顶堆解决Top K问题的思路:小顶堆维护当前扫描到的最大100个数,其后每一次的扫描到的元素,若大于堆顶,则入堆,然后删除堆顶;依此往复,直至扫描完所有元素。
Python heapq 模块
第一种: nlargest
import heapq
b = [('a',6),('b',2),('c',5),('d',1),('e',3)]
# 对前面的对象中的第二维数据(即value)的值进行排序。 key=lambda 变量:变量[维数]
data = heapq.nlargest(3,b,key=lambda x:x[1])
print(data)
打印结果:
[('a', 6), ('c', 5), ('e', 3)]
第二种:heappush() + heappushpop() 注:只跑前K个数据
import heapq
h = []
b = [('a',6),('b',2),('c',5),('d',1),('e',3)]
for i in range(len(b)):
if i < 3:
heapq.heappush(h, (b[i][1], b[i][0]))
else:
heapq.heappushpop(h, (b[i][1], b[i][0]))
print(h)
借鉴文章: