乙個隨機序列,找出序列的中位數,當序列個數為奇數時,為中間位置上的數字;當序列為偶數時,為中間兩個數字的平均值。
這種題有很多種做法,比較有代表性的由:
1、partition法
利用快排關鍵字的查詢方法
a.隨機選取乙個關鍵字key,將序列二分;
b.若關鍵字的下標大於n/2,則繼續對序列的左半部分執行partition;
c.若關鍵字的下標小於n/2,則繼續對序列的左半部分執行partition;
d.若關鍵字的下標等於n/2,則返回key。
這種演算法:partition的時間複雜度為o(n),獲取中位數的時間複雜度為o(1)。
2、利用平衡二叉查詢樹
沒讀取乙個數字,將數字插入到二叉樹中,並調整二叉樹的平衡性。最後根節點就是想要的中位數。
構建平衡二叉查詢樹的演算法時間複雜度為o(logn),取出中位數的時間複雜度為o(n)。但是調整平衡二叉查詢樹演算法實現比較複雜。
3.利用堆
原理分析:中位數無非就是將序列分為兩個部分,左邊的部分都小於中位數,右邊的序列都大於中位數。這比較符合堆的特性(看看資料結構在演算法中的重要性,選擇好的資料結構能夠讓演算法事半功倍)。可以將序列分成兩個部分,左邊的部分夠著大根堆,右邊的部分構造小根堆。
具體實現細節:
a.如果堆中元素的個數為偶數時,將新數字插入小根堆中(插入後堆元素的個數為奇數,此時結束插入,返回小根堆堆頂元素);如果堆中的元素個數為奇數時,將新數字插入大根堆中(插入後堆元素的個數為偶數,此時結束插入,返回兩堆堆頂元素的均值)。
b.若插入小根堆的元素大於大根堆堆頂的元素,說明新元素位於序列的右半部分,應當插入大根堆。而此時大根堆堆頂元素應當位於左半序列(小頂堆)中,因此需要將大根堆堆頂元素插入小根堆。若插入若插入小頂堆的元素不大於大頂堆堆頂的元素,則直接插入小根堆。
c.同理,向大根堆插入元素時也有如上考慮。
調整堆的時間複雜度為o(logn),取中位數的時間複雜度為o(1)。
演算法實現:
template
class solution
maxheap.push_back(num);
push_heap(maxheap.begin(),maxheap.end(),less());
}else
minheap.push_back(num);
push_heap(minheap.begin(),minheap.end(),greater());}}
t getmedian()
};
從海量資料中找出中位數
題目 在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可 記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體 關於中位數 資料排序後,位置在最中間的數值。即將資料分成兩部分,一部分大於該數值,一部分小於該數值...
從海量資料中找出中位數
題目 在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可 記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體 關於中位數 資料排序後,位置在最中間的數值。即將資料分成兩部分,一部分大於該數值,一部分小於該數值...
中位數的中位數
參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...