在线求中位数

在线求第k个数做得多了,在线求中位数也是用堆,一个最大堆,一个最小堆。

思想大概是这样子的:

  1. 一个最大堆,一个最小堆,最大堆对应于前n/(n+1)个数,最小堆对应于后n/n+1个数;假设最大堆堆项元素为n1, 最小堆堆顶为n2, 则n1 <= n2;
  2. 确保两个堆的大小最多只差1. 设最大堆大小为s1, 最小堆大小为s2,则abs(s1-s2) <= 1;
  3. 对于新来的数m,分情况调整:
    1. 如果s1== s2, 那么:如果m<= n2, m插入到最大堆,s1= s1+1; 否则插入到最小堆,s2=s2+1;
    2. 如果s1 > s2, 那么:如果m >= n1, m插入到最小堆,s2=s2+1;否则,n1pop出最大堆,然后push进最小堆,然后m进最大堆,s2=s2+1;
    3. 如果s1 < s2, 那么:如果m <=n2, m插入到最大堆,s1=s1+1;否则,n2pop出最小堆,然后push进最大堆,然后m进最小堆,s1=s1+1;

代码如下:

时间: 2024-07-29 08:06:13

在线求中位数的相关文章

在线求中位数 TOJ3515

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <set> 5 6 using namespace std; 7 8 multiset<int> smin; 9 multiset<int> smax; 10 multiset<int>::iterator it; 11 char arr[5]; 12 13 int main(

在线求中位数(优先队列实现) POJ3784

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 8 priority_queue<int,vector<int>,greater<int> >pq2; 9 priority_queue<int> pq1; 10 11 int main() 12

URAL 1306 - Sequence Median 小内存求中位数

[题意]给出n(1~250000)个数(int以内),求中位数 [题解]一开始直接sort,发现MLE,才发现内存限制1024k,那么就不能开int[250000]的数组了(4*250000=1,000,000大约就是1M内存). 后来发现可以使用长度为n/2+1的优先队列,即包含前一半的数以及中位数,其他数在读入的时候就剔除,这样可以省一半的空间. 1 #include<bits/stdc++.h> 2 #define eps 1e-9 3 #define FOR(i,j,k) for(in

POJ 2388 Who&#39;s in the Middle(水~奇数个数排序求中位数)

题目链接:http://poj.org/problem?id=2388 题目大意: 奇数个数排序求中位数 解题思路:看代码吧! AC Code: 1 #include<stdio.h> 2 #include<algorithm> 3 using namespace std; 4 int main() 5 { 6 int n; 7 while(scanf("%d",&n)!=EOF) 8 { 9 int na[n+1]; 10 for(int i=0; i

求中位数

求中位数 题目描述 输入n和n个数,求大于中位数的数据个数.(n小于50) 中位数是把一列数从小到大排列后,中间的那个数!如果那一列数是偶数,就取中间两个数的平均数! 例如: 第1组数:1.2.3.6.7的中位数是3. 第2组数:1.2.3.5的中位数是2.5. 输入描述 输入正整数n和n个实数 输出描述 1.输出中位数保留小数1位.中位数输出占一行. 2.输出大于中位数的数据个数占一行. 样例输入 4 1 2 3 5 样例输出 2.5 2

POJ 3784 Running Median 动态求中位数 堆

题意. 1000个case 每个case 输入若干个数,对第k个输入,如果k为奇数,则输出前k个数的中位数 那么这就是动态求中位数了 实现的思路也比较简洁 用两个堆, 大顶堆和小顶堆 每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中,  否则就存入大顶堆. 然后调整, 小顶堆元素的个数要等于大顶堆的元素个数,或者比其多1. 如果小顶堆的元素太多,就塞到大顶堆里,反之亦然 这样一来就会发现.小顶堆的元素比所有大顶堆的元素都大, 而且小顶堆的堆顶就是中位数. 那么怎么样才能想到这样一个思路

线性求中位数 poj2388

在做uva11300时,遇到了n < 1000 000的中位数,就看了一下线性求中位数. 和快排的思想很像,同理,线性求第k大数,算法如下: ①以某个数x将一段数组分成两部分,比x小的放在左边,比x大的放在右边 ②如果x刚好是出于要找的位置的,直接返回 ③如果在x的左边,则递归在x的右边找 ④如果在x的右边,则递归在x的左边找 代码如下: 1 /*=============================================================== 2 * Copyrig

双堆求中位数

堆 堆的动态创建与删除可参考 http://www.java3z.com/cwbwebhome/article/article1/1362.html?id=4745,此处不再赘述. 双堆求中位数 算法描述: 1.创建两个堆(一个小根堆.一个大根堆),堆大小至少为给定数据个数的一半,向上取整: 2.假定变量mid用来保存中位数,取定第一个元素,赋值给mid,即作为初始的中位数: 3.依次遍历后面的每一个数据,如果比mid小,则插入大根堆:否则插入小根堆: 4.如果大根堆和小根堆上的数据个数相差为2

LeetCode题目----求中位数---标签:Array

题目难度---困难 题目要求: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 思路:第一眼看到题目两个数组求中位数,看似很复杂,但是仔细一想,两个数组合在一块不久行了?然后合并后的数组给他排序,进而判断是奇数位数组还是偶数位数组 ok!代码奉上: public static double findMedianSortedArrays(int[] nums1, int[] nums2) {