题目链接: leetcode.
排序会超时
/*
16 / 18 个通过测试用例
*/
class MedianFinder {
public:
vector<int> _nums;
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
_nums.push_back(num);
sort(_nums.begin(), _nums.end());
}
double findMedian() {
if(_nums.empty())
return 0.0;
int N = _nums.size();
double ans = 0;
if(N % 2 == 0)
{
ans += _nums[N / 2];
ans += _nums[(N / 2) - 1];
ans /= 2;
}
else
{
ans = _nums[N / 2];
}
return ans;
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
官解表示可以用两个优先队列,小一半和大一半的数分开存
两个优先级队列:
1.用于存储较小一半数字的最大堆minn
2.用于存储较大一半数字的最小堆 maxx
即当堆完全平衡时,中间值可以从两个堆的顶部派生。否则,最大堆 minn 的顶部保留合法的中间值
——
添加一个数 num:
1.将 num 添加到最大堆 minn。因为 minn 收到了一个新元素,所以我们必须为 maxx 做一个平衡步骤。因此,从minn中移除最大的元素并将其提供给 maxx。
2.在上一个操作之后,最小堆 maxx 可能会比最大堆 minn保留更多的元素。我们通过从 maxx中去掉最小的元素并将其提供给 minn来解决这个问题。
——https://leetcode-cn.com/problems/find-median-from-data-stream/solution/shu-ju-liu-de-zhong-wei-shu-by-leetcode/
/*
执行用时:140 ms, 在所有 C++ 提交中击败了66.27%的用户
内存消耗:40.8 MB, 在所有 C++ 提交中击败了65.78%的用户
*/
class MedianFinder {
public:
priority_queue<int> minn;
priority_queue<int, vector<int>, greater<int> > maxx;
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
minn.push(num);
int tmp = minn.top();
minn.pop();
maxx.push(tmp);
if(maxx.size() > minn.size())
{
tmp = maxx.top();
maxx.pop();
minn.push(tmp);
}
}
double findMedian() {
if(_nums.empty())
return 0.0;
double ans = 0;
if(minn.size() == maxx.size())
{
ans += minn.top();
ans += maxx.top();
return ans/2;
}
ans = minn.top();
return ans;
}
};