數據結構與算法面試題彙編(2)- 海量數據處理

1、從海量日誌數據中提取出某日訪問百度次數最多的那個IP。

    算法思想:分而治之 + Hash
1)IP地址最多有2^32=4G種取值情況,所以不能完全加載到內存中處理;
2)可以考慮採用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日誌分別存儲到1024個小文件中。這樣,每個小文件最多包含4MB個IP地址;
3)對於每一個小文件,可以構建一個IP爲key,出現次數爲value的Hash map,同時記錄當前出現次數最多的那個IP地址;
4)可以得到1024個小文件中的出現次數最多的IP,再依據常規的排序算法得到總體上出現次數最多的IP;

2、從海量日誌記錄中提取最頻繁字符串:搜索引擎會通過日誌文件把用戶每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度爲1-255字節。假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。一個查詢串的重複度越高,說明查詢它的用戶越多,也就是越熱門。),請你統計最熱門的10個查詢串,要求使用的內存不能超過1G。

    問題解析:要統計最熱門查詢,首先就是要統計每個Query出現的次數,然後根據統計結果,找出Top 10。
    算法思想:Hash表統計 + TOP K算法
1)維護一個key爲檢索串,value爲出現次數的hash table,讀一遍日誌,每出現一個key,將對應的value加1,使用內存≈300W*256B ≈ 700MB
2)求該hash表中vaue的top 10。維護一個節點爲10的小根堆。遍歷hash表,與小根堆的根比較,更新堆。

3、有一個1G大小的一個文件,裏面每一行是一個詞,詞的大小不超過16字節,內存限制大小是1M。返回頻數最高的100個詞。

    問題解析:將1G文件全讀入內存需要1024M。一次讀取時不可能實現的。需要按一定規則把大文件分割成小文件,保證每個小文件中出現的單詞不會在其他文件中出現,統計每個小文件中出現次數最多的詞,最後合併。
    算法思想:分而治之 + Hash
1)順序讀取文件中每一個詞key,按照key的Hash(key)%1024的值,將詞寫入0,1,2,...,1023號的小文件當中。這樣每個小文件最多包含1MB的詞
2)對於每個小文件,構造一個爲詞爲key,以出現次數爲value的hash table,同時記錄當前出現次數最多的那個詞
3)建立100個節點的小根堆,遍歷這1024個文件中出現最多的詞的頻率與小根堆的根比較,更新堆。

4、有10個文件,每個文件1G,每個文件的每一行存放的都是用戶的query,每個文件的query都可能重複。要求你按照query的頻度排序。

    問題解析:首先需要將相同的query寫入到一個文件內,然後文件內按query的頻度排序,最後輸出再輸出。 
    算法思想:
    方案一、不考慮內存等限制
1)可依次讀入10個文件的每行query,組建以query爲key,以出現次數爲value的hash table。
2)按照次數對query做快排/堆/歸併排序
3)輸出每個query出現的次數和query到另一個文件
     方案二、考慮內存限制
1)依次讀入文件,按照hash(query)%10,分別將每條query輸出到另外的10個文件中
2)分別對每個文件再次讀入並按照每個query出現的次數進行快速/堆/歸併排序,並輸出次數和query到另一個文件中。
3)對這10個內容已排序的文件,進行歸併排序,將最終結果輸出

5、給定a、b兩個文件,各存放50億個url,每個url各佔64字節,內存限制是4G,讓你找出a、b文件共同的url?
    問題解析:50億個url*64B = 320G。內存限制4G,因此要把每個文件至少分成120份兒纔可(假設均勻分佈),而文件分的越小,處理越快,
    算法思路:分而治之+hash
1)讀入a,按hash(url)%1000,將之分別輸入到a0,a1,a2,...,a999這1000個文件中
2)讀入b,按hash(url)%1000,將之分別輸入到b0,b1,b2,...,b999這1000個文件中
3)只需比較<a0,b0>,<a1,b1>,...,<a199,b199>這1000組文件即可。
4)對每組文件,將a文件錄入,構造以url爲key的hash set;然後讀b文件,如果在hash set中存在,這改url在a,b兩個文件中均有。
    方案2:如果允許有一定的錯誤率,可以使用Bloom filter,4G內存大概可以表示340億bit。將其中一個文件中的url使用Bloom filter映射爲這340億bit,然後挨個讀取另外一個文件的url,檢查是否與Bloom filter,如果是,那麼該url應該是共同的url(注意會有一定的錯誤率)。

6、在2.5億個整數中找出不重複的整數,注,內存不足以容納這2.5億個整數。
    算法思想:
    方案一、採用分而治之的方法。先分割成小文件,在小文件中找不重複的整數。
    方案二、採用2位位圖法。此種方法假設這2.5個整數是32位整數,則每兩位表示所在索引表示該數,表示所有整數範圍一共需要2^32*2=1G內存(如果是64位整數,就不行了)。設申請的內存塊爲B,依次讀入每個整數N,檢查B[2N]和B[2N+1]如果是00,這變爲01,如果是01這變爲10,如果是10,則不變化。最後再遍歷一遍該內存塊,輸出01對應的索引。

7、騰訊面試題:給40億個不重複的unsigned int的整數,沒排過序的,然後再給一個數,如何快速判斷這個數是否在那40億個數當中?
    方案一、採用1位位圖法,申請2^32bit = 512MB的內存B,依次讀入N,並置B[N]=1,再給一個數M,如果B[M]的值即可。
    方案二、另類的分而治之。按每位是0或1將之分割成小文件。

8、怎麼在海量數據中找出重複次數最多的一個?
    算法思想:分而治之+hash(參考第一題)

9、上千萬或上億數據(有重複),統計其中出現次數最多的前N個數據。
    算法思想:分而治之+hash(參考第二題)

10、一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10個詞,請給出思想,給出時間複雜度分析。
    算法思想:讀入文件,建立hash_map(word, word_count);建立10個以出現次數和單詞爲節點的小根堆,讀入所有hash_map元素,更新堆。
    算法分析:時間複雜度爲O(n*log10)

11、100w個數中找出最大的100個數。
方案1:在前面的題中,我們已經提到了,用一個含100個元素的最小堆完成。複雜度爲O(100w*lg100)。
方案2:採用快速排序的思想,每次分割之後只考慮比軸大的一部分,知道比軸大的一部分在比100多的時候,採用傳統排序算法排序,取前100個。複雜度爲O(100w*100)。
方案3:採用局部淘汰法。選取前100個元素,並排序,記爲序列L。然後一次掃描剩餘的元素x,與排好序的100個元素中最小的元素比,如果比這個最小的要大,那麼把這個最小的元素刪除,並把x利用插入排序的思想,插入到序列L中。依次循環,知道掃描了所有的元素。複雜度爲O(100w*100)。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章