TopK问题

该博客探讨了在海量数据中寻找前K个最大值的TopK问题。当数据无法全部加载到内存时,通过构建小顶堆来解决。算法首先存储前K个数据入堆,然后遍历剩余数据,将大于堆顶的元素替换并保持堆的性质。时间复杂度为O(nlogk),空间复杂度为O(k)。提供的C++代码展示了如何实现这个过程。
摘要由CSDN通过智能技术生成
TopK-在海量数据中找出前K个最值的问题
对于此类问题,我们一般想到的算法是排序算法,首先给数据进行排序,再去获取k个最值
但是当问题的规模内存中放不下时,普通的内排序就无法进行。对于海量数据的topk问题,一种常用的做法是借助堆解决。

如果需要获取最大的k个值,可以建小堆
首先读入前k个数据存入一个最小堆
然后遍历后续的数据,对于每一个遍历的数据,都和堆顶(k个数据中最小的)数据比较
如果比堆顶数据小,则继续遍历后续数据
如果比堆顶数据大,则删除堆顶元素,存入当前遍历到的数据
整个过程直到所有数据遍历完为止

时间复杂度
如果数据量为n,找到topK个元素,则每次堆的插入和删除时间复杂度为logk。
最坏情况下,对于每一个元素都要进行堆的插入和删除,则最坏时间复杂度为O(nlogk)
最好情况下,前k个元素即为topK个元素,堆不需要进行调整,则最好时间复杂度为O(n)
空间复杂度
需要一个大小为k的堆保存topK个元素,故空间复杂度为O(k)
priority_queue<int>topk(vector<int>nums, int k){
        priority_queue<int>mmq;
        for (int num : nums){
               if (mmq.size() < k || mmq.top()<num){
                       mmq.push(num);
               }
               if (mmq.size()>k){
                       mmq.pop();
               }
               return mmq;
        }
}
vector<int>findtopk(vector<int>&nums, int k){
        priority_queue<int>mq = topk(nums, k);
        vector<int>v;
        while (!mq.empty()){
               v.push_back(mq.top());
               mq.pop();
        }
        return v;
}

topK的场景
有海量个查询字符串记录,统计最热门的K个查询串
从一个大文件中找出频数最高的K个词
找出某日访问网站次数最多的K个IP
只要涉及到从数据中找出k个最值的问题都属于topK问题
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值