TopK问题

TopK注意数据量的问题,也就是内存是否能都进来。

数据量小
首先很容易想到的就是全排序的方法,但是这样的复杂度高,做的无效比较多,因为只需要知道top的元素,不需要全部排序,因此,会让你容易想到部分排序:

1.快速排序:借助于partition的概念,分为大于基准值和小于基准值部分。然后再依次进行分块,直到找到K个元素的partittion。
2.冒泡排序:进行K趟排序,找到TopK。

海量数据
1.利用分布式的原理。将数据分成多个部分,算出每个部分的topK,再在这么多的topK中找到最终的TopK。
2.利用经典的堆排序,可以在单机上完成海量数据的topK。堆排序是一种树形选择排序,所有结点都是待比较的数据。

面试问题:
1.有10亿个元素,先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的),将这个数替换堆顶,并调整结构使之仍然是一个最小堆,这样,遍历完后,堆中的10000个数就是所需的最大的10000个。建堆时间复杂度是O(mlogm),算法的时间复杂度为O(nmlogm)(n为10亿,m为10000)。

    优化的方法:可以把所有10亿个数据分组存放,比如分别放在1000个文件中。这样处理就可以分别在每个文件的10^6个数据中找出最大的10000个数,合并到一起在再找出最终的结果。

2.在搜索引擎中,统计搜索最热门的10个查询词;在歌曲库中统计下载最高的前10首歌等。
针对top K类问题,通常比较好的方案是分治+Trie树/hash+小顶堆(就是上面提到的最小堆),即先将数据集按照Hash方法分解成多个小数据集,然后使用Trie树或者Hash统计每个小数据集中的query词频,之后用小顶堆求出每个数据集中出现频率最高的前K个数,最后在所有top K中求出最终的top K。

你可能感兴趣的:(TopK问题)