动态中位数-----------------------------------对顶堆
程序员文章站
2024-02-14 10:07:10
...
解析:
我们需要两个优先队列,一个大根堆和一个小根堆。
一开始我们往小根堆放,但是放到小根堆是有条件的,当前数x必须>=小根堆堆顶元素。
否则放到大根堆去。我们还需要平衡一下这两个堆的元素个数。
如果大根堆的元素个数>小根堆的元素个数,需要从大根堆移动元素移到小根堆,使其平衡
如果大根堆的元素个数+1<小根堆的元素个数**(就是大根堆元素个数至少要比小根堆元素个数少2个**),需要从小根堆移动元素到大根堆,使其平衡
那么中位数就是小根堆堆顶的元素
https://www.bilibili.com/video/av41618192?from=search&seid=5749560244515488750
作者视频讲解。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10000;
int a[N];
int t,n,op,x;
priority_queue<int,vector<int> ,greater<int> > q1;//小根堆
priority_queue<int,vector<int> ,less<int> > q2;//大根堆
int main()
{
scanf("%d",&t);
while(t--)
{
int cnt=0;
scanf("%d %d",&op,&n);
cout<<op<<" "<<(n+1)/2<<endl;
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(q1.empty()) q1.push(x);
else
{
if(x>q1.top()) q1.push(x);
else q2.push(x);
while(q1.size()<q2.size())
{
q1.push(q2.top());
q2.pop();
}
while(q1.size()>q2.size()+1)
{
q2.push(q1.top());
q1.pop();
}
}
if(i&1)
{
cnt++;
cout<<q1.top()<<" ";
if (!(cnt%10))
cout<<endl;
}
}
if(cnt%10) cout<<endl;
}
}
推荐阅读
-
黑盒子--------------------------------思维(对顶堆)
-
Binary Tree Traversals(ACM训练 - 对顶堆学习笔记)
-
动态中位数(对顶堆)
-
动态中位数-----------------------------------对顶堆
-
JAVA 堆的使用 (大顶堆,小顶堆)即优先队列 再TopK 和求中位数中用此种数据结构
-
(leetcode 295)数据流的中位数(暴力、二分、小顶堆以及进阶)
-
PAT 1057. Stack (30) 求动态数据的中位数, 堆的插入和删除
-
POJ 3784 Running Median G++ 堆巧妙 求动态中位数 背
-
对顶堆
-
Running Median 对顶堆 数据流中的中位数