leetcode-295 数据流的中位数
生活随笔
收集整理的這篇文章主要介紹了
leetcode-295 数据流的中位数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。
例如,
[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
針對該問題,由于數組是動態增加的,我們使用傳統的查找中位數的方式為:有序數組取中間兩位(奇數個數字,取中間一位數字;偶數個數字,取中間兩個數字的平均值),那么每次我們增加一個數字就需要重新排序,代價太大
此時我們可以維護兩個堆,最大堆存儲較小元素,最小堆存儲較大元素,且兩個堆大小相差不能超過1;此時,我們僅需要每次調整兩個堆的堆頂元素即可。
計算中位數時,根據兩個堆各自的大小,分別取堆頂進行計算求值。該過程就是會出現重建堆較為耗時(O(nlogn))之外再沒有需要消耗時間的地方了
實現如下:
class MedianFinder {
public:/** initialize your data structure here. */MedianFinder() { }void addNum(int num) {if (big_heap.empty()) {big_heap.push(num);} else {//當最大堆元素個數大于最小堆元素個數,此時需要向最小堆插入if(big_heap.size() > small_heap.size()) { //但是發現插入的元素 小于 最大堆的元素個數//規則是:最小堆堆頂元素一定大于最大堆的堆頂,所以需要調整最大堆堆頂if (num < big_heap.top()) {small_heap.push(big_heap.top());big_heap.pop();big_heap.push(num);} else {small_heap.push(num);}} else {if (num > small_heap.top()) {big_heap.push(small_heap.top());small_heap.pop();small_heap.push(num);} else {big_heap.push(num);}}}}double findMedian() {if (big_heap.size() > small_heap.size()) {return big_heap.top();} else if (big_heap.size() == small_heap.size()) {return (double)(big_heap.top() + small_heap.top()) / 2.0;} else {return small_heap.top();}}
private:priority_queue<int, vector<int>, greater<int>> small_heap;priority_queue<int, vector<int>, less<int>> big_heap;
};
總結
以上是生活随笔為你收集整理的leetcode-295 数据流的中位数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大家对莱昂纳多,德普,小罗伯特唐尼,皮特
- 下一篇: 好的不孕不育专家