最小的K個數

2021-07-10 23:52:29 字數 939 閱讀 4710

題目:輸入n個整數,找出其中最小的k個數。

例如輸入4、5、1、6、2、7、3、8這8個數字,則最小的4個數字是1、2、3、4。

1、最簡單的思路:對輸入的n個整數排序,輸出位於前面的k個數。

第一想到的是快速排序,時間o(nlgn).然後輸出前面的k個數,o(k)

所以時間複雜度為o(nlogn+k)=o(nlgn).

2、遍歷n個數,先把最先遍歷到得k個數存入大小為k的陣列之中,對這k個數,利用選擇或交換排序,找到k個數中的最大數kmax,用時o(k),後再繼續遍歷後n-k個數,x與kmax比較:

如果x小於kmax,則x代替kmax,並再次重新找出k個元素的陣列中最大元素kmax;如果x>kmax,則不更新陣列。這樣,每次更新或不更新陣列的所用的時間為o(k)或o(0),整趟下來,總的時間複雜度平均下來為:n*o(k)=o(n*k)。

3、更好的辦法是維護k個元素的最大堆,原理與上述第2個方案一致,即用容量為k的最大堆儲存最先遍歷到的k個數,並假設它們即是最小的k個數,建堆費時o(k)後,有kmax設為大頂堆中最大元素。繼續遍歷數列,每次遍歷乙個元素x,與堆頂元素比較,x小於kmax,更新堆(用時logk),否則不更新堆。這樣下來,總費時o(k+(n-k)*logk)=o(n*logk)。此方法得益於在堆中,查詢等各項操作時間複雜度均為logk(不然,就如上述思路2所述:直接用陣列也可以找出前k個小的元素,用時o(n*k))。

4、n個數儲存在陣列s中,從陣列中隨機選取乙個數x,把陣列劃分為sa和sb倆部分,sa<=x<=sb,如果要查詢的k個元素小於sa的元素個數,則返回sa中較小的k個元素,否則返回sa中所有元素+sb中小的k-|sa|個元素。

像上述過程一樣,這個運用類似快速排序的partition的快速選擇select演算法尋找最小的k個元素,在最壞情況下亦能做到o(n)的複雜度。不過值得一提的是,這個快速選擇select演算法是選取陣列中「中位數的中位數」作為樞紐元,而非隨機選取樞紐元。

最小的K個數

問題描述 給定的n個整數,計算其中最小的k個數。最直觀的解法莫過於將n個數按公升序排列後輸出前k個。但是就效率來看,這種方法並不是最理想的。一種改進方法是借助快速排序中對陣列的劃分,以第k個元素對陣列進行劃分,使得比第k個數字小的數字都在其左邊,比其大的數字都在它的右邊。void swap int ...

最小的K個數

從 陣列中出現次數超過一半的數字 得到啟發,同樣可以基於partition函式來解決。一 o n 演算法 void getleastnumbers int input,int n,int output,int k else for int i 0 i k i output i input i 二 o...

最小的K個數

輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,如果不讓使用sort的話,自己實現乙個,或者依次選取最小的 class solution public vectorgetleastnumbers solution vectori...