從4300000000箇中找出重複的數

http://www.onlymarshall.com/2008/10/16/%E4%B8%80%E9%81%93%E7%BC%96%E7%A8%8B%E7%8F%A0%E7%8E%91%E7%9A%84%E9%A2%98%EF%BC%8C%E7%BB%88%E4%BA%8E%E6%90%9E%E6%87%82%E4%BA%86/

給定一個包含4300000000個32位整數的順序文件,請問如何找到一個至少出現兩次的整數?

順序文件,不允許隨機訪問。

    解答:Binary Search,但不是對文件內容折半,而是對搜索範圍折半。由於4.3G>32位的整數空間,根據鴿籠原理,肯定會有重複的整數。搜索範圍從所有的32位正整數開始(全部當成unsigned int,簡化問題),即[0, 2^32),中間值即爲2^31。然後遍歷文件,如果小於2^31的整數個數大於2^31,則調整搜索範圍爲[0, 2^31],反之亦然;然後再對整個文件再遍歷一遍,直到得到最後的結果。這樣一共會有logn次的搜索,每次過n個整數(每次都是完全遍歷),總體的複雜度爲o(nlogn)。

    例子:數組[4,2,5,1,3,6,3,7,0,7],假定從3位的整數空間內搜索。第一次的範圍爲[0,8),遍歷過後發現[0,4)範圍內的整數個數爲5,於是調整爲搜索[0,4)範圍內的整數。第二次發現[2, 4)範圍內的證書爲3,大於2,於是調整爲[2, 4)。再經過第三次的遍歷,找出3爲重複出現的整數。

    改進:上面的辦法有很多的冗餘。於是提出了一個辦法:建立一個新的文件(是順序文件就可以)。在一次遍歷過後,確定搜索的範圍後,把原有文件裏這個範圍內的整數寫到新的文件裏去,下次搜索就只要搜索這個新文件了。這樣可以得到近似線性的複雜度(但是常數項應該很大)。

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