尋找最大的K個數,Top K問題的堆實現

2021-09-22 09:41:39 字數 1159 閱讀 5614

參考:

如果不能把所有資料的資料都一次性放入記憶體,就可以維護乙個大小為k的堆,找最大的k個數,就維護乙個小根堆,堆頂元素為這最大的k個數中的最小元素。具體實現參考下面兩個例子:

2億個整數中求最大的100萬之和

題目:有乙個檔案中儲存了2億個整數,每個整數都以' '分隔。求最大的100萬個整數之和。

演算法:1. 首先建立乙個容量為100萬(top k)的int陣列,從檔案讀取整數填充。

2. 利用堆維護該100萬條記錄(確保堆頂元素為最小值)

3. 從檔案中讀取乙個整數與堆頂元素比較,如果大於堆頂元素則替換該元素,並調整堆的結構。

4. 重複步驟3一直到資料讀取完

5. 將陣列中的元素全部相加,得到結果

參考**:

測試資料:生成1000萬個不重複的隨機數

1000萬個資料太大,開啟檔案很慢,可能會看不到,可以測試1萬個資料中找最大的10個。

搜尋引擎熱門查詢統計

題目描述:

搜尋引擎會通過日誌檔案把使用者每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255位元組。

假設目前有一千萬個記錄,這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。乙個查詢串的重複度越高,說明查詢它的使用者越多,也就是越熱門。請你統計最熱門的10個查詢串,要求使用的記憶體不能超過1g。

解決方法:hash表+堆,去重複後不超過300萬個,總大小不超過300萬*255b=765mb,記憶體使用不超過1g。

第一步:先對這批海量資料預處理,在o(n)的時間內用hash表完成去重複操作。

第二步:借助堆這個資料結構,找出top k,時間複雜度為nlogk。即借助堆結構,可以在log量級的時間內查詢和調整/移動。因此,維護乙個k(該題目中是10)大小的小根堆(kmin設為堆頂元素),然後遍歷300萬的query,分別和kmin進行對比比較(若x>kmin,則更新並調整堆,否則,不更新),最終的時間複雜度是:o(n)+ n'*o(logk),(n為1000萬,n』為300萬)。

為了降低實現上的難度,假設這些記錄全部是一些英文單詞,即使用者在搜尋框裡敲入乙個英文單詞,然後查詢搜尋結果,最後,要你統計輸入單詞中頻率最大的前k個單詞。複雜問題簡單化了之後,編寫**實現也相對輕鬆多了,如下:

參考:

尋找最大的K個數 TOP K演算法

前言 本文是對程式設計之美第2.5節以及博文的一些總結和心得 問題描述 有很多個無序的數,怎麼從中選出其中最大的若干數呢?這個問題中的很多可以是幾個數也可以使成百上億的數,針對此問題我們有以下解法 解法一 咱們先簡單的理解,要求乙個序列中最小的k個數,按照慣有的思維方式,很簡單,先對這個序列從小到大...

尋找最大的k個數,TopK問題的C 實現

2億個整數中求最大的100萬之和 題目 有乙個檔案中儲存了2億個整數,每個整數都以 分隔。求最大的100萬個整數之和。演算法 1.首先建立乙個容量為100萬 ntop 的int陣列,從檔案讀取整數填充。2.利用堆維護該100萬條記錄 確保堆頂元素為最小值 3.從檔案中讀取乙個整數與堆頂元素比較,如果...

尋找最大的K個數

方法一 改進的快速排序 分割槽時,根據數p將陣列分為兩部分,設大於p的數個數為a,小於p的數的個數為b。如果,a k,則從這a個數取最大的k個數,若a時間複雜度是o nlogk include includevoid swap float a,float b int fun float n,int ...