本文为剑指 offer 系列第六十篇。
主要知识点为数组,依旧是数组遍历然后分析找中位数,比较简单。
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
解题思路
思路1
找一个数组,用来存储所有插入的数据,并保持数组内的数据有序(可以用插入排序的方式)。
在获得中间数的时候,可以通过奇偶直接从数组中获取处理并返回。
思路2
在进行插入的时候可以直接使用stl的upper_bound获得对应的插入位置。
解题代码
思路1代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution { public: void Insert(int num) { mvec.push_back(num); len++; //sort(mvec.begin(),mvec.end()); int i = len; for( ; i >= 1; i--){ if(num<=mvec[i]){ mvec[i] = mvec[i-1]; }else{ break; } } mvec[i] = num; } double GetMedian() { int mindex = (len-1)/2; if(len%2 == 0){ return ((mvec[mindex]+(double)mvec[mindex+1])/2); }else{ return (double)mvec[mindex]; } } private: vector<int> mvec; int len = 0; };
时间复杂度为O(n),空间复杂度为O(n)
思路2代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class MedianFinder { public: /** initialize your data structure here. */ MedianFinder() { } void addNum(int num) { auto a = upper_bound(mvec.begin(),mvec.end(),num); mvec.insert(a, num); } double findMedian() { int mid = mvec.size()/2; if(mvec.size()%2 == 0){ return (double)(mvec[mid]+mvec[mid-1])/2; }else{ return (double)mvec[mid]; } } private: vector<int> mvec; }; /** * Your MedianFinder object will be instantiated and called as such: * MedianFinder* obj = new MedianFinder(); * obj->addNum(num); * double param_2 = obj->findMedian(); */
PS:思路2代码是在leetcode网站剑指offer模块面试题41. 数据流中的中位数 实现的.
以上,本题结束!