做题总结——中位数

做题总结——中位数

题目
中位数 题目

题意分析:

这道题目题意其实并不理解,相当于在插入数据的过程中动态求中位数,每当插入奇数个数据时就求这所有奇数个数据的中位数。

做题思路:

  • 开始看见这道题目,最暴力的思路肯定就是每当插入奇数个数据时,就将这奇数个数据排序,从而能够求得中位数(但可想而知这样的做法肯定会超时)。 自己还是什么都不会,也没有什么思路,后来通过大神的分析发现其实这道题目有许多种不同的做法,利用了不同的数据结构。

  • 这里自己使用的方法是堆的思想,建立一个大顶堆和一个小顶堆,mid代表比较变量(开始时是第一个数据元素,后面会进行更新)。如果插入的元素小于mid,则将该元素插入到大顶堆中,否则将该元素插入到小顶堆中,根据大顶堆、小顶堆各自的性质可以知道,大顶堆中的每一个元素都小于小顶堆中的元素。每当插入奇数个元素时,判断大顶堆中的元素个数与小顶堆中的元素个数是否相等(这是因为对于奇数个数据,大于中位数的元素个数=小于中位数的元素个数),如果大顶堆中的元素个数多于小顶堆,则将mid压入小顶堆,大顶堆中根结点的元素成为新的mid,重复该过程直至两个堆中元素个数相等;反之,如果如果小顶堆中的元素个数多于大顶堆,则将mid压入大顶堆,小顶堆中根结点的元素成为新的mid,重复该过程直至两个堆中元素个数相等,最后得到的mid就是所求的中位数。

代码实现

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
	int n,a[200000],mid;
	cin>>n;
	//利用优先队列实现堆的结构
	priority_queue<int,vector<int>,less<int> > lar;            //建立一个大根堆
	priority_queue<int,vector<int>,greater<int> > sma;    //建立一个小根堆
	cin>>a[1];
	mid=a[1];           //开始时mid时第一个数据元素
	cout<<a[1]<<endl;
	for(int i=2;i<=n;i++)
	{
    
    
		cin>>a[i];
		if(a[i]>mid)
		{
    
    
			sma.push(a[i]);
		}
		else
		{
    
    
			lar.push(a[i]);
		}
		if(i&1)                           //看网上的代码看到一位大神这样写的,其实相当于判断i是否是奇数
		{
    
    
			while(sma.size()!=lar.size())              //当两个堆的元素个数不相等时
			{
    
    
				if(sma.size()>lar.size())
				{
    
    
					lar.push(mid);
					mid=sma.top();
					sma.pop();
				}
				else
				{
    
    
					sma.push(mid);
					mid=lar.top();
					lar.pop();
				}
			}
			cout<<mid<<endl;
		}
	}
	return 0;
}
```**加粗样式**

猜你喜欢

转载自blog.csdn.net/m0_46772594/article/details/108112628