LeetCode 295 資料流的中位數

2021-10-01 07:43:18 字數 1992 閱讀 6071

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

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

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

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

void addnum(int num) - 從資料流中新增乙個整數到資料結構中。

double findmedian() - 返回目前所有元素的中位數。

示例:addnum(1)

addnum(2)

findmedian() -> 1.5

addnum(3) 

findmedian() -> 2

高階:如果資料流中所有整數都在 0 到 100 範圍內,你將如何優化你的演算法?

如果資料流中 99% 的整數都在 0 到 100 範圍內,你將如何優化你的演算法?

按照題目要求,最簡單的方法是維持乙個動態陣列,在每次執行插入操作時將元素num儲存到動態陣列中;在每次findmedian時先將陣列排序,再查詢中位數返回結果。該方法超時,本文不進行介紹。下面介紹其他兩種解決方法:

(1)兩個堆的方法,即維護乙個最大堆和乙個最小堆,最大堆中儲存小於等於中位數的元素,最小堆中儲存大於中位數的元素。如果陣列的長度n為奇數時,最大堆的堆頂即為結果;如果n為偶數,最大堆和最小堆的堆頂元素的平均值即為結果。該方法的難點在於怎麼平衡兩個堆中元素的個數,平衡方法請見**。

(2)multiset 和雙指標,利用multiset(內部的資料結構為自平衡二進位制搜尋樹)自動排序的功能。我們保持兩個指標:乙個用於中位數較低的元素,另乙個用於中位數較高的元素。當元素總數為奇數時,兩個指標都指向同乙個中值元素(因為在本例中只有乙個中值)。當元素數為偶數時,指標指向兩個連續的元素,其平均值是輸入的代表中位數。其中兩個指標的更新方式,請見**。

(1)兩個堆的方法

class medianfinder

void addnum(int num)

}double findmedian()

};/**

* your medianfinder object will be instantiated and called as such:

* medianfinder* obj = new medianfinder();

* obj->addnum(num);

* double param_2 = obj->findmedian();

*/

(2)multiset + 雙指標方法

class medianfinder

void addnum(int num)

else if(n & 1) //n為奇數時,插入num之後變為偶數

else //num插入到大於等於中位數的一邊

}else //n為偶數時,插入num之後變為奇數

else if(num >= *r_mid) //num插入到大於等於右中位數的一邊

else // num <= *l_mid < *r_mid 注意當num == *l_mid時,num插入到l_mid和r_mid的中間}}

double findmedian()

};/**

* your medianfinder object will be instantiated and called as such:

* medianfinder* obj = new medianfinder();

* obj->addnum(num);

* double param_2 = obj->findmedian();

*/

(1)兩個堆的方法

(2)multiset + 雙指標方法

LeetCode 295 資料流的中位數

中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 示例 addnum 1 addnum 2 findmedian 1.5 addnum 3 findmedian 2...

LeetCode 295 資料流的中位數

中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 void addnum int num 從資料流中新增乙個整數到資料結構中。double findmedian 返...

leetcode 295 資料流的中位數

中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 void addnum int num 從資料流中新增乙個整數到資料結構中。double findmedian 返...