找出乙個陣列裡面前K個最大數

2021-05-26 19:23:30 字數 1974 閱讀 9993

問題:找出乙個陣列裡面前k個最大數。

解法:1.第一感覺就是對陣列進行降序全排序,然後返回前k個元素,即是需要的k個最大數。

排序演算法的選擇有很多,考慮陣列的無序性,可以考慮選擇快速排序演算法,其平均時間複雜度為o(nlogn)。具體**實現可以參見相關資料結構與演算法書籍。

2.觀察第一種演算法,問題只需要找出乙個陣列裡面前k個最大數,而第一種演算法對陣列進行全排序,不單單找出了前k個最大數,更找出了前n(n為陣列大小)

個最大數,顯然該演算法存在「冗餘」,因此基於這樣乙個原因,提出了改進的演算法二。 

首先建立乙個臨時陣列,陣列大小為k,從n中讀取k個數,降序全排序(排序演算法可以自行選擇,考慮陣列的無序性,可以考慮選擇快速排序演算法),然後依 次

讀入其餘n - k個數進來和第k名元素比較,大於第k名元素的值則插入到合適位置,陣列最後乙個元素溢位,反之小於等於第k名元素的值不進行插入操作。

只待迴圈完畢返回臨時陣列的k個元素,即是需要的k個最大數。同演算法一其平均時間複雜度為o(klogk + (n - k))。具體**實現可以自行完成。

演算法時間複雜度證明:

原問題:

順序統計量選擇問題:陣列a包含n個元素,找出陣列a中前k個最大數

解法二:

首先建立乙個臨時陣列,陣列大小為k,從n中讀取k個數,降序全排序(可以考慮選擇快速排序演算法,快排平均複雜度o(klogk)),

然後依次讀入其餘n - k個數進來和第k名元素比較,大於第k名元素的值則插入到合適位置,陣列最後乙個元素溢位,反之小於等於第k名元素的值不進行插入操作。

只待迴圈完畢返回臨時陣列的k個元素,即是需要的k個最大數。

其平均時間複雜度為o(klogk + (n - k))。

證明:設指示器隨機變數

xi = ,i=k+1, k+2, ..., n;

由於陣列a的n個元素分布隨機,則e[xi] = 1/n;

則依次處理其餘n - k個數的時間複雜度為t(n-k) = sum(xi*logk),i=k+1, k+2, ..., n;

(注意logk是將乙個數插入到排好序的k個數的時間複雜度)

對上式求期望,得

e[t(n-k)] = e[sum(xi*logk),i=k+1, k+2, ..., n]

= sum(e[xi] * logk),i=k+1, k+2, ..., n

= sum(1/n * logk),i=k+1, k+2, ..., n

= (n-k)logk/n < n-k;

綜合,該演算法平均時間複雜度為

t(n) = o(klogk + (n - k))。

3.上面兩種演算法在n=100萬,k=50萬時速度都尤其「漫長「,現在提出一種更高效的演算法,該演算法原理和快速排序一致,但只有乙個方向的遞迴,其平均時間

複雜度為

o(n)。

先選取乙個中值元素(該中值是否合理將影響到演算法效率,其原因同快速排序),然後將大於等於該數的元素放到其右側,小於該數的放到左側。如7 4 6 8 0 

-1,選取6作為中值元素,則結果應該為4 0 -1 6 8 7,接下來比較k值和現在的中值元素6所在索引(3)。

如果k小於索引3,則處於包括中值元素在內的右邊的元素即是前k個最大數中的前(3(索引) - k + 1)個最大數,予以儲存,同時需在索引0 ~ 2間再進行遞迴

操作繼續選取第k名。

如果k大於索引3,則在4 ~ 5中遞迴選取第k - 3(索引) - 1名即可。

還有一關鍵是可以為遞迴中的陣列長度選取一臨界點,小於該臨界則進行全排序,而不再

進行遞迴操作。

以上演算法均是本人在書本上或者網際網路上學習的演算法,並非自己原創,當然部分的改動還是自我原創的。

其實當問題規模不是很大時,比如陣列大小n很小,n為100數量級,可以不用太追求演算法的高效性,因為對於問題規模不大時,上面三種演算法的執行時間相差並不大,

完全可以考慮採用第一種或者第二種比較簡單的實現方式。

C 求乙個整型陣列裡面和最大的子陣列

求子陣列的最大和 題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。include include using namespace std vectorsearcharray const int arr,int size 使用const可以...

求乙個陣列的最大k個數(java)

問題描述 求乙個陣列的最大k個數,如,的最大三個數應該是,8,9,11 問題分析 1.解法一 最直觀的做法是將陣列從大到小排序,然後選出其中最大的k個數,但是這樣的解法,複雜度是o logn n 但是有時候並不需要排序,用簡單的選擇排序,或者是氣泡排序,那麼就k輪的交換或者是選擇,就可以得出結論,複...

找出乙個陣列中的前k個高頻元素

給定乙個非空的整數陣列,返回其 現頻率前 k 高的元素。例如,給定陣列 1,1,1,2,2,3 和 k 2,返回 1,2 注意 你可以假設給定的 k 總是合理的,1 k 陣列中不相同的元素的個數。第一步基本都是一致的,需要統計出每個元素的出現次數 先遍歷一遍陣列,以陣列的值做key存放到map中,初...