17、【常见算法】topN问题
題 目:如果在N個數中找出其中前K大的數?
思路一:
先對N個數進行排序,然后在取其前K大的數;(冒泡排序,快速排序等)
思路二:
部分排序,只排除前K大的數即可(使用選擇排序進行部分排序,選擇排序的時間復雜度O(N2))
思路三:
我可以用分治法,這有點類似快排中partition的操作。隨機選一個數t,然后對整個數組進行partition,會得到兩部分,前一部分的數都大于t,后一部分的數都小于t。
如果說前一部分總數大于1000個,那就繼續在前一部分進行partition尋找。如果前一部分的數小于1000個,那就在后一部分再進行partition,尋找剩下的數。
該思路的事件復雜度為O(N):首先,partition的過程,時間是o(n)。我們在進行第一次partition的時候需要花費n,第二次partition的時候,數據量減半了,所以只要花費n/2,同理第三次的時候只要花費n/4,以此類推。而n+n/2+n/4+...顯然是小于2n的,所以這個方法的漸進時間只有o(n)。
思路四:
當N的值過大,且內存資源有限,無法一次讀取全部數據時,可以考慮分布式的實現,將數據切分,然后在多臺機器上分別計算前K大的數,最后在把這些數據匯總。
思路五:
使用最小堆思想。即在內存中維護一個有K個數組成的最小堆;根據最小堆每一個節點都要比他的左右直接點小的性質:
首先從N個數中取K個數構成最小堆;
然后依次讀取剩余數據,并且和堆頂元素比較大小,如果比堆頂小,則直接丟棄。如果比堆頂大,就替換堆頂,并調整最小堆;
所有數據都處理完畢后,最小堆就是N個數中前K大的數。
優點是:數據只需要讀取一次,不會存在數據多次讀寫的問題;
【思路五的C++實現】
【待更新。。。。】
總結
以上是生活随笔為你收集整理的17、【常见算法】topN问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: svn authz 授权文件模版
- 下一篇: c# Winform Control 快