在海量資料中找出出現頻率最高的前k個數,或者從海量資料中找出最大的前k個數,這類問題通常被稱為topk問題。
下面我們通過乙個簡單的例子來說明:假如面試官給你100w個資料,請找出其最大的前k個數,而且現在只有1m的空間?
在32位作業系統中,預設乙個位元組為4個位元組,則有下列運算:
needsize = 100w * 4 / 1024 /1024 = 4m
計算結果大約等於4m,很顯然1m的空間根本不夠。也就是說,即使用最複雜的方法你也無法找到乙個合適的空間來儲存,因此引入了最小堆資料結構。
(1)定義兩個陣列,arr用於儲存海量資料,top用於儲存最小堆(底層可以借助vector)
(2)將海量資料的前k個元素先填滿top堆
(3)調整top堆為最小堆結構
(4)通過遍歷將新資料與堆頂元素(此時堆頂元素是堆裡最小的資料)進行比較,大於堆頂就入堆,並向下調整堆結構
(5)遍歷結束,則堆中的元素即n個數中最大的前k個
#pragma once
#include#includeusing namespace std;
#define n 100000
//向下調整(最小堆)
templatevoid adjustdown(t* top,size_t root,size_t k)
//從第乙個非葉子結點開始向下調整
for(int end = (k-2)/2;end >= 0;end--)
//此時小堆已經形成
for(size_t j = k;j < n;++j) }
//遍歷完成,top陣列內儲存的就是最大的前k個數
for(size_t index = 0;index < k;index++)
//自定義仿函式,比較map鍵值對的第二個元素即水果出現的次數
struct compare
};//2.通過優先順序佇列來建立小堆,對水果出現的次數進行排序
priority_queue::iterator, vector::iterator>, compare> _pq;
map::iterator it = _map.begin();
while(it != _map.end())
//3.列印次數最多的k種水果
while(k--)
海量資料topK問題
給你一億個資料,從中找出前k個大的資料。有兩種解決辦法。1.直接將資料從大到小排序,然後取前k個。但是由於資料的數量過於龐大,要開闢很大的空間,很浪費記憶體,所以這種方法不建議使用。2.用堆來解決。要找前k個大的資料,則將待找的元素的前k個元素建立大小為k的小根堆,小根堆的堆頂元素是這k個資料中最小...
海量資料的TopK問題
乙個基本的是思想是分治法,將1億個資料分成100份,每份100萬個資料,找出每份中最大的100個,最終可以在這100 100個資料中找出最大的100個。我們知道,快排一次的結果是分界點前面的資料比他小,分界點後的比他大,我們可以做如下的討論 如果分界點後面的資料個數大於k個,那麼可以在後面的資料中重...
求海量資料的topK問題
問題描述 取給定list中的前topk個最大的元素並輸出。關鍵點 1.topk個最大的元素 2.我們並不需要順序,因此一切涉及到sort的工作都是不必要的。3.要且只要topk個元素,no more needed!因此,我們雖然用堆,但並不需要將整個list都建成堆,只需要維護乙個k個元素的堆即可。...