面试题-10亿个数中找出最大的10000个数(top K问题)

一个较好的方法:先拿出10000个建立小根堆,对于剩下的元素,如果大于堆顶元素的值,删除堆顶元素,再进行插入操作,否则直接跳过,这样知道所有元素遍历完,堆中的10000个就是最大的10000个。时间复杂度: m + (n-1)logm = O(nlogm)

优化的方法:可以把所有10亿个数据分组存放,比如分别放在1000个文件中(如果是字符串hash(x)%M)。对每个文件,建立大小为10000的小根堆,然后按有序数组的合并合并起来,取出最大的10000个即是答案。

top K问题

在大规模数据处理中,经常会遇到的一类问题:在海量数据中找出出现频率最好的前k个数,或者从海量数据中找出最大的前k个数,这类问题通常被称为top K问题。例如,在搜索引擎中,统计搜索最热门的10个查询词;在歌曲库中统计下载最高的前10首歌等。

解决方法:针对top K类问题,通常比较好的方案是分治+Trie树/hash+小顶堆(就是上面提到的最小堆),即先将数据集按照Hash方法分解成多个小数据集,然后使用Trie树或者Hash统计每个小数据集中的query词频或频数,之后用小顶堆求出每个数据集中出现频率最高的前K个数,最后在所有top K中求出最终的top K。

简陋的实现:

估计能处理1e8个整数(约400M)吧

#include<bits/stdc++.h>
using namespace std;

int n, k, tmp;
priority_queue<int, vector<int>, greater<int>>qu;

int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 0;i < k;i++)
    {
        scanf("%d", &tmp);
        qu.push(tmp);
    }
    for(int i = 0;i < n-k;i++)
    {
        scanf("%d", &tmp);
        if(tmp > qu.top())
        {
            qu.pop();
            qu.push(tmp);
        }
    }
    for(int i = 0;i < k;i++)
    {
        printf("%d ", qu.top());
        qu.pop();
    }

    return 0;
}

参考链接:

1. CSDN_yofer张耀琦-海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

2. 牛客网-100w个数中找最大的100个数

扫描二维码关注公众号,回复: 9603557 查看本文章

猜你喜欢

转载自www.cnblogs.com/lfri/p/12422423.html