數字中找前K大 小的元素的幾種方法

2021-08-22 08:54:53 字數 1329 閱讀 6305

方法一:根據快速排序劃分的思想 :

(1) 遞迴對所有資料分成[a,b)b(b,d]兩個區間,(b,d]區間內的數都是大於[a,b)區間內的數 ;

(2) 對(b,d]重複(1)操作,直到最右邊的區間個數小於100個。

注意[a,b)區間不用劃分 ;因為[a,b)區間一定小於(b,d]區間;
(3) 返回上乙個區間,並返回此區間的數字數目。

如果個數大於100,對(b,d]重複(1)操作,直到最右邊的區間個數小於100個;

如果個數小於100,對上一區間的左邊進行劃分,分為[a2,b2)b2(b2,d2]兩個區間,取(b2,d2]區間。

如果個數超過100的就重複1操作,直到最後右邊只有100個數為止。 時間複雜度為:o(n)

方法二:維護乙個k個元素的堆:

先取出前100個數,維護乙個100個數的最小堆,遍歷一遍剩餘的元素,在此過程中維護堆就可以了。
具體步驟如下:

第一:取前k個元素(例如m=100),建立乙個小頂堆。保持乙個小頂堆得性質的步驟,執行時間為o(lgk);建立乙個小頂堆執行時間為k*o(lgk)=o(klgk);       

第二:順序讀取後續元素,直到結束。每次讀取乙個元素,如果該元素比堆頂元素小,直接丟棄 ;如果大於堆頂元素,則用該元素替換堆頂元素,然後保持最小堆性質。最壞情況是每次都需要替換掉堆頂的最小元素,因此需要維護堆的代價為(n-k)*o(lgk);

最後這個堆中的元素就是前k最大的k個元素。時間複雜度為o(n lgk)。

方法三:維護乙個k個元素的陣列:

這種思想類似與思想二,如果在查詢比較的時候用二分查詢,也可以使時間複雜度變為:o(nlgk)。只不過因為陣列時順序儲存,當需要插入更新資料的時候需要移動k個資料,移動的次數變得很多,操作變得複雜。如果是堆,移動的次數最多也是lgk次。所以在這方面堆的效率比陣列高。

方法四:分塊查詢:

如果資料有100w個,求取前100個資料。那麼我們可以用分治法的思想,其實對於大量的資料一般都是分治法。大而化小,小而化簡,各個擊破。最後在組合。因為資料是無限的,而我們的處理資源硬體是有限的,所以必須的分割處理。

方法是:先把100w個數分成100份,每份1w個數。先分別找出每1w個數裡面的最大的數,然後比較。找出100個最大的數中的最大的數和最小的數,取最大數的這組的第二大的數,與最小的數比較。如果第二大的數比最小的數大,那麼這樣就一下砍掉1w個數了;如果第二大的數比最小的數小,那麼也可以砍掉9999個數,剩下的肯定不是前100個中的。類似這樣可以解決此問題。

個人覺得,現在的計算講究分布式,並行處理,最後一種方法其實才是實用中最快的。

找n個數字中第k小的元素

利用快速排序的方法尋找第k小的資料,該方法的時間複雜度平均為o n 可以滿足一般情況下的查詢演算法 include res代表開始查詢的元素的位址,n代表查詢的範圍,nth代表查詢該範圍內的第nth小的元素 int findnth int res,int n,int nth int i 0,j n ...

TextBox中只能輸入數字的幾種常用方法 C

private void tbox keypress object sender,keypresseventargs e catch private void textbox keypress object sender,keypresseventargs e 或者private void text...

Oracle中sql直接處理數字的幾種方式

向下取整 select floor 5.534 from dual select trunc 5.534 from dual 上面兩種用法都可以對數字5.534向下取整,結果為5.向上取整 select ceil 5.534 from dual 保留n位小數 四捨五入 select round 5....