劍指 Offer 41 資料流中的中位數

2021-10-21 11:03:55 字數 1700 閱讀 3771

題目:資料不斷的進入,要求實現addnum()和findmedian()兩個函式。來進行數字的新增和中位數的查詢。

public void addnum(int num)

public double findmedian()

思路:1.先說一下基本的思路:

可以對目前的資料進行排序,如使用快速排序o(nlogn),然後直接返回中間的那個數o(1)。

2.一:維護較大元素區間的minheap和乙個維護較小元素區間的maxheap

二:怎麼維持?用什麼條件判斷?(addnum的實現內容)

三:返回中位數時用什麼條件判斷?

用乙個維護較大元素區間的minheap和乙個維護較小元素區間的maxheap來做,時間複雜度為o(logn)(堆的操作時間複雜度為o(logn)),空間複雜度為o(n)。

為什麼乙個(維護較大元素)minheap和乙個(維護較小元素)maxheap可以實現查詢中位數?

因為維護較大元素的minheap的堆頂元素和維護較小元素的maxheap堆頂元素分別對應乙個有序序列中間的2個數或1個數。就相當於用這兩個不同的堆模擬了乙個有序序列從中間分為兩半。這兩個堆的元素從乙個方向看正好是乙個有序序列。這樣就可以獲得中位數。

如何維持維護較大元素區間的minheap和維護較小元素區間的maxheap?

首先把乙個元素加入maxheap,然後經過堆調整後,把maxheap堆頂元素加入到minheap,這樣就把大的元素(maxheap出來的是最大值)慢慢地放到了minheap中,就維持較大區間了。反過來也是,這樣就可以維持。

注意:1.其實第一下加到哪個heap都行

2.返回兩堆頂的和/2.0,一定要/2.0化為double。size不相等時總體元素數為單數,返回minheap堆頂元素。

3.用minheap和maxheap的size()來判斷

/*

先說一下有什麼基本思路

思路:用兩個堆,乙個大頂堆,乙個小頂堆。

大頂堆維護著較小的區間序列,小頂堆維護著較大的區間序列。

如果minheap和maxheap的總和是奇數,那麼中位數就是minheap的堆頂(第一步先往maxheap放)

如果minheap和maxheap的總和是偶數,那麼中位數就是minheap和maxheap各自堆頂的平均數。

怎麼維護各自一直是較大或較小區間呢?

每加進堆乙個元素,就把該堆的堆頂元素放到另一堆裡,

這樣就能保證較大的區間序列就一直是較大的,較小的區間序列就一直是較小的。

*/priorityqueue

minheap = null;

priorityqueue

maxheap = null;

public

medianfinder()

public

void

addnum

(int num)

else

}public

double

findmedian()

劍指 Offer 41 資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 示例...

《劍指offer》 41 資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 vo...

劍指Offer41 資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 輸入...