[LeetCode]295. Find Median from Data Stream

Description:

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

Examples: 

[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

  • void addNum(int num) - Add a integer number from the data stream to the data structure.
  • double findMedian() - Return the median of all elements so far.

For example:

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3) 
findMedian() -> 2

———————————————————————————————————————————————————

Solution:

題意:在可變數組下,高效地尋找這一組數的中位數。

思路:

【TLE】①使用插入排序,每次addNum時將新加進來的數插入到已經排好序的vector當中。

時間複雜度:O(logn) + O(n) ~ O(n)。其中O(logn)是用二分查找法尋找插入位置的時間,O(n)是講n後面的數往後挪一位的時間。

【TLE】②使用快速排序,每次addNum時將新加入的數放到vector的最後,然後用快排隊整個vector進行排序。

時間複雜度:O(nlogn)

【AC】③使用雙堆排序,priority_queue,分別是大堆排序和小堆排序。

時間複雜度:O(5*logn)。其中5指推入和推出堆的次數,logn指推入和推出堆的時間。結合代碼比較容易理解。

class MedianFinder {
private:
    priority_queue<int, vector<int>, less<int>> lowQueue;
    priority_queue<int, vector<int>, greater<int>> highQueue;
public:
    /** initialize your data structure here. */
    MedianFinder() {
    }
    
    void addNum(int num) {
        lowQueue.push(num);
        highQueue.push(lowQueue.top());
        lowQueue.pop();
        
        // balanced
        if (lowQueue.size() < highQueue.size()) {
            lowQueue.push(highQueue.top());
            highQueue.pop();
        }
    }
    
    double findMedian() {
        return highQueue.size() == lowQueue.size() ? (double) (highQueue.top() + lowQueue.top()) / 2 : (double) lowQueue.top();
    }
};

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章