1. 程式人生 > >從100萬個數中找出最大的前100個數

從100萬個數中找出最大的前100個數

1.演算法如下:根據快速排序劃分的思想 (1) 遞迴對所有資料分成[a,b)b(b,d]兩個區間,(b,d]區間內的數都是大於[a,b)區間內的數 (2) 對(b,d]重複(1)操作,直到最右邊的區間個數小於100個。注意[a,b)區間不用劃分 (3) 返回上一個區間,並返回此區間的數字數目。接著方法仍然是對上一區間的左邊進行劃分,分為[a2,b2)b2(b2,d2]兩個區間,取(b2,d2]區間。如果個數不夠,繼續(3)操作,如果個數超過100的就重複1操作,直到最後右邊只有100個數為止。

2.先取出前100個數,維護一個100個數的最小堆,遍歷一遍剩餘的元素,在此過程中維護堆就可以了。具體步驟如下: step1:取前m個元素(例如m=100),建立一個小頂堆。保持一個小頂堆得性質的步驟,執行時間為O(lgm);建立一個小頂堆執行時間為m*O(lgm)=O(m lgm); step2:順序讀取後續元素,直到結束。每次讀取一個元素,如果該元素比堆頂元素小,直接丟棄 如果大於堆頂元素,則用該元素替換堆頂元素,然後保持最小堆性質。最壞情況是每次都需要替換掉堆頂的最小元素,因此需要維護堆的代價為(N-m)*O(lgm); 最後這個堆中的元素就是前最大的10W個。時間複雜度為O(N lgm)。

補充:這個方法的說法也可以更簡化一些: 假設陣列arr儲存100個數字,首先取前100個數字放入陣列arr,對於第101個數字k,如果k大於arr中的最小數,則用k替換最小數,對剩下的數字都進行這種處理。

3.分塊查詢 先把100w個數分成100份,每份1w個數。先分別找出每1w個數裡面的最大的數,然後比較。找出100個最大的數中的最大的數和最小的數,取最大數的這組的第二大的數,與最小的數比較。。。。