剑指 Offer 41. 数据流中的中位数
Posted lxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 41. 数据流中的中位数相关的知识,希望对你有一定的参考价值。
方法一:插入排序
解题思路
每次添加一个数字时,通过插入排序添加,需要返回中位数时,根据元素个数进行返回。
代码
class MedianFinder
private:
vector<int> nums;
public:
/** initialize your data structure here. */
MedianFinder()
void addNum(int num)
nums.push_back(num);
for (int i = nums.size() - 1; i > 0; i -- )
if (nums[i] < nums[i - 1]) swap(nums[i], nums[i - 1]);
else break;
double findMedian()
int cnt = nums.size();
if (cnt == 0) return NULL;
int mid = cnt / 2;
if (cnt % 2 == 0) return (nums[mid] + nums[mid - 1]) / 2.0;
else return nums[mid];
;
复杂度分析
执行用时:1360 ms, 在所有 C++ 提交中击败了5.04%的用户
内存消耗:40.7 MB, 在所有 C++ 提交中击败了59.16%的用户
通过测试用例:18 / 18
\\(addNum()\\):时间复杂度为\\(O(n)\\),空间复杂度为\\(O(1)\\);
\\(findMedian()\\):时间复杂度为\\(O(1)\\),空间复杂度为\\(O(1)\\)。
方法二:优先队列
解题思路
通过优先队列维护两个数组\\(queMin\\) 和 \\(queMax\\),\\(queMin\\)保存数据流中较小的一部分数(从大到小),\\(queMax\\)保存数据流中较大的一部分数(从小到大),\\(queMax.size() - queMin.size() == 0 || 1\\),则样\\(queMin.top()\\) 和 \\(queMax.top()\\)就是数据流中间的\\(1\\)个数 或 中间的\\(2\\)个数。
代码
class MedianFinder
private:
priority_queue<int, vector<int>, less<int>> queMin;
priority_queue<int, vector<int>, greater<int>> queMax;
public:
/** initialize your data structure here. */
MedianFinder()
void addNum(int num)
if (queMin.empty() || num < queMin.top())
queMin.push(num);
if (queMax.size() + 1 < queMin.size()) // queMax元素数量少于queMin元素数量超过1个
queMax.push(queMin.top()); // 将queMin的最大值转移到queMax中,保持平衡
queMin.pop();
else
queMax.push(num);
if (queMax.size() > queMin.size()) // queMax元素数量超过queMin元素数量
queMin.push(queMax.top()); // 将queMax的最小值转移到queMin中,保持平衡
queMax.pop();
double findMedian()
if (queMin.size() > queMax.size()) return queMin.top();
return (queMin.top() + queMax.top()) / 2.0;
;
复杂度分析
执行用时:84 ms, 在所有 C++ 提交中击败了93.98%的用户
内存消耗:40.7 MB, 在所有 C++ 提交中击败了33.52%的用户
通过测试用例:18 / 18
\\(addNum()\\):时间复杂度为\\(O(logn)\\),空间复杂度为\\(O(1)\\);
\\(findMedian()\\):时间复杂度为\\(O(1)\\),空间复杂度为\\(O(1)\\)。
剑指offer数据流中的中位数
题目链接:数据流中的中位数
题意:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
题解:啊我这题用暴力做的。。正解应该是最大堆最小堆。。和之前一个题一样。后面再补。
暴力就是sort一下找中位数。
代码:
class Solution { public: vector<int> number; void Insert(int num) { number.push_back(num); } double GetMedian() { sort(number.begin(),number.end()); int len = number.size(); double ans; if(len % 2) ans = (double)number[len/2]; else ans = (double)(number[len/2-1]+number[len/2])/2; return ans; } };
以上是关于剑指 Offer 41. 数据流中的中位数的主要内容,如果未能解决你的问题,请参考以下文章