面試題-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個數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM