一.題目連接:ios
https://leetcode.com/problems/find-median-from-data-streamless
二.題目大意:spa
給定一段數據流,要求求出數據流中的中位數,其中數據流是動態變化的。若是數據流中的數字個數是奇數的話,則中位數是中間位置的數字;若是數據流中的數字是偶數的話,則中位數是排序好的數據流中的中間兩個數的的平均值。code
三.題解:blog
若是數據流是靜態不變的話,此時問題是比較好求解的。可是數據流是動態變化的,因此數據流中每次進入一個新的數字時,都要保證可以高效的找到數據流的中位數。咱們能夠這麼考慮:若是把數據流中的數字分爲個數相同的兩部分的話(假設爲A和B,其中A中的數字所有小於B中的數字),那麼咱們所求的中位數,實質就是A中的最大值和B中的最小值的平均值。所以,咱們能夠用兩個堆來表示這個過程,其中大頂堆maxH存儲的是數據流中的數值較小的數字,而小頂堆minH存儲的是數據六中數值較大的數字,且maxH中的數字所有小於minH中的數字。而且堆能夠快速的找出其中的最值,因此能夠快速找獲得minH中的最小值和maxH中的最大值,從而求出中位數。代碼以下:排序
#include<iostream> #include<unordered_map> #include<queue> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<sstream> #include<set> #include<map> #include<stack> #define MAX_NUM 100 using namespace std; class MedianFinder { public: /** initialize your data structure here. */ priority_queue<int,vector<int>,less<int>> maxH;//定義大頂堆,用於存儲較小的數據部分 priority_queue<int,vector<int>,greater<int>> minH;//定義小頂堆,用於存儲較大的數據部分 MedianFinder() { } void addNum(int num) { maxH.push(num); int tmp = maxH.top(); maxH.pop(); minH.push(tmp);//保證小頂堆中的數據大於大頂堆中的數據 if(minH.size() > maxH.size()) { int tmp = minH.top(); minH.pop(); maxH.push(tmp);//保證大頂堆中的數據小於小頂堆中的數據 } } double findMedian() { if(minH.size() == maxH.size())//若是兩個堆的大小相同,則返回它們最值的平均值 return (minH.top() + maxH.top()) / 2.0; return minH.size() > maxH.size() ? minH.top() : maxH.top();//若是兩個堆的大小不相同,返回數字個數多的堆的最值 } }; /** * Your MedianFinder object will be instantiated and called as such: * MedianFinder obj = new MedianFinder(); * obj.addNum(num); * double param_2 = obj.findMedian(); */ int main() { MedianFinder test = MedianFinder(); test.addNum(1); test.addNum(2); test.addNum(3); test.addNum(4); test.addNum(5); cout<<test.findMedian()<<endl; }
每次從數據流中找出中位數的時間爲O(1),調整兩個堆的時間爲O(logN),對於含有n個數字的數據流,總的時間複雜度爲O(NlogN),空間複雜度爲O(N)。隊列
此外,有幾個點須要注意下:leetcode
1.代碼中使用了priority_queue即優先隊列來實現堆,由於優先隊列獲取優先級最高的值所需時間爲O(1),調整的過程爲O(logN),與堆的操做時間相似,能較好的模擬堆。get
2.一般狀況下,堆默認的優先級最高的值是指的最大值,也能夠是最小值,不過須要顯式的說明(見本例中優先隊列的定義)。string
3.要保證最小堆中存儲的始終是較大的數值,而大頂堆中存儲的是較小的數值。因此纔會有addNum中的那些操做。