欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态中位数-----------------------------------对顶堆

程序员文章站 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;
		
	}
 } 
相关标签: 算法进阶指南