1. 程式人生 > >LeetCode 295. 數據流的中位數

LeetCode 295. 數據流的中位數

fin 一個 如果 平均值 序列 color size truct pri

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

例如,

[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

這個題太過巧妙,我是直接學習LeetCode英文版的解答的。在這個題中,使用了兩個堆(優先隊列)。其中,一個堆為大頂堆,一個堆為小型堆。大頂堆存數組左邊的數據,小頂堆存數組右邊的數據。那麽,小頂堆堆頂和大頂堆對頂是唯一提供中位數的可能來源。

為了保持大頂堆和小頂堆的平衡,設定小頂堆比大頂堆最多存儲多一個元素。

至於添加操作,首先是把添加元素放入大頂堆。再把大頂堆的最大元素轉移到小頂堆。如果小頂堆比大頂堆大,再把小頂堆元素轉移到大頂堆。

class MedianFinder {
    priority_queue<int> lo;                              // max heap
    priority_queue<int, vector<int>, greater<int>> hi;   // min heap

public:
    // Adds a number into the data structure.
void addNum(int num) { lo.push(num); // Add to max heap hi.push(lo.top()); // balancing step lo.pop(); if (lo.size() < hi.size()) { // maintain size property lo.push(hi.top()); hi.pop(); } }
// Returns the median of current data stream double findMedian() { return lo.size() > hi.size() ? (double) lo.top() : (lo.top() + hi.top()) * 0.5; } };

LeetCode 295. 數據流的中位數