C 實現乙個資料流中,隨時可以取得中位數

2021-09-25 09:58:18 字數 2008 閱讀 2846

leetcode295: 資料流的中位數

中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。

例如,[2,3,4] 的中位數是 3

[2,3] 的中位數是 (2 + 3) / 2 = 2.5

設計乙個支援以下兩種操作的資料結構:

void

addnum

(int num)

- 從資料流中新增乙個整數到資料結構中。

double

findmedian()

- 返回目前所有元素的中位數。

示例:

addnum(1

)addnum(2

)findmedian()

->

1.5addnum(3

)findmedian()

->

2

採用優先佇列,也就是大根堆跟小根堆,我們將較小的n/2個數放到大根堆中,將較大的n/2個數放到小根堆中,顯然,如果n是偶數,那麼大根堆的堆頂跟小根堆的堆頂就是我們要找的兩個中位數,將其相加除以2作為結果返回即可。如果n是奇數,那麼就看大根堆跟小根堆誰的節點個數比另乙個堆多乙個,節點數量多的那個堆的堆頂就是我們要找的中位數,此時我們直接返回結果即可。

注意:

對於取堆頂元素的操作的時間複雜度是常數級別的。

插入新節點時我們需要判斷節點的值是否小於大根堆堆頂的值或者大於小根堆堆頂的值,如果小於大根堆堆頂的值,那麼節點應該插入大根堆,反過來應該插入小根堆。

每次插入新節點我們還需要判斷兩個堆之間的元素個數是否平衡。插入新節點後,我們判斷兩個堆的元素個數,如果相差為2那麼我們就要對堆進行調整。比如新插入乙個節點到小根堆中,而此時大根堆的個數+1小於小根堆的節點個數,這個時候只需要將小根堆的堆頂元素彈出,然後將這個彈出的元素插入大根堆即可。反過來也是一樣的操作。為什麼可以這樣做呢?這是因為我們說了小根堆儲存的是較大的n/2個數,而小根堆的堆頂是小根堆中最小的元素,同時也是大根堆中最大的元素,因此我們將這個堆頂元素彈出並插入大根堆的操作並不會破壞「小根堆儲存較大的n/2個數,大根堆儲存較小的n/2」這樣的前提。

這裡還是借助了std::priority_queue來實現大跟堆和小根堆。

leetcode-295 資料流的中位數

貪心的題目暫時到這裡,後面可能是動態規劃的一些題目了。

Practice52 得到乙個資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用insert 方法讀取資料流,使用getmedian 方法獲取當前讀取資料的中位數。暴力解法 class ...

資料流中第乙個唯一的數字

給乙個連續的資料流,寫乙個函式返回終止數字到達時的第乙個唯一數字 包括終止數字 如果在終止數字前無唯一數字或者找不到這個終止數字,返回 1.您在真實的面試中是否遇到過這個題?yes 樣例給乙個資料流 1,2,2,1,3,4,4,5,6 以及乙個數字5,返回3 給乙個資料流 1,2,2,1,3,4,4...

資料流中的中位數 C 實現

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用insert 方法讀取資料流,使用getmedian 方法獲取當前讀取資料的中位數。牛客網題目鏈結 如題,...