一.题目连接: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中的那些操做。