…
topK 一般解法
- 全局排序
- O(nlogn)的时间复杂度
- 数据量不大的时候简单可行
- 局部淘汰 / 局部排序
- 【类选择排序】对目标序列N个数遍历,取出其中最大的数最为Top1;再次遍历剩下的N-1个数,取出其中最大的数为Top2;….再对剩下的N-K+1个数遍历,取出其中最大的数为TopK。可以用冒泡k次实现
- O(n)的时间复杂度
- 【partition】每一轮排序都会将序列一分为二,左子区间的数都小于pivot,右子区间的数都大于pivot,按情况对左区间或右区间递归
- O(n)的时间复杂度
- 需要提前将N个数读入,空间开销较大;如果是动态数据,即可能会不停的增加新数据,那么就还需要每插入一个新数据就将其与前面取出的TopK做比较,排除K+1个数中最小的,最后剩下的才是TopK。
- 小根堆(优先队列):只找到TopK,不排序TopK
- 先用前k个元素生成一个小顶堆,这个小顶堆用于存储当前最大的k个元素。
- 只需要将堆顶元素与下一个数比较:如果下一个数大于堆顶元素,则将当前的堆顶元素抛弃,并将该元素插入堆中。
- O(N * logk)的时间复杂度
- 对于海量数据,我们不需要一次性将全部数据取出来,可以一次只取一部分
- 对于动态数组,无论任何时候需要查询当前的前 K 大数据,我们都可以里立刻返回
小顶堆:每个结点的值都 <= 其左右孩子结点的值的【完全二叉树】
优先队列:在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先被访问(poll、delete…)。元素在队列尾追加。
堆 等效于 优先队列
海量数据
频率统计
找出一个数据流中最频繁出现的k个数,比如热门搜索词汇等。
例:统计一篇英文文章中频次出现最高的10个单词
- 数据量不大时可使用HashMap进行频率统计,求统计结果的topk
- Count-Min Sketch方法
- Trie树解决