寻找中位数(分治+双堆)
来源:互联网 发布:华为云计算招聘西安 编辑:程序博客网 时间:2024/06/05 23:47
比如5亿个int,寻找它们的中位数。
思路是先分治,再用双堆法:
首先我们将int划分为2^16个区域,然后读取数据统计落到各个区域里的数的个数,之后我们根据统计结果就可以判断中位数落到那个区域。然后第二次扫描我们只统计落在这个区域中的那些数就可以了。
双堆法的思路:
序列中的元素,前一半存储在一个最大堆中,后一半存储在一个最小堆中。控制MaxHeap与MinHeap的大小差不能超过1。具体操作如下:
1.如果 num < MaxHeapTop,则 1.1 如果 MaxHeapSize <= MinHeapSize,将num插入最大堆; 1.2 如果 MaxHeapSize > MinHeapSize,将MaxHeapTop从最大堆中移到最小堆,然后将num插入最大堆。2.如果 MaxHeapTop <= num <= MinHeapTop,则 2.1 如果 MaxHeapSize < MinHeapSize,将num插入最大堆; 2.2 如果 MaxHeapSize > MinHeapSize,将num插入最小堆; 2.3 如果 MaxHeapSize == MinHeapSize,随意插,看心情。3.如果 num > MinHeapTop,则 3.1 如果 MaxHeapSize >= MinHeapSize,将num插入最小堆; 3.2 如果 MaxHeapSize < MinHeapSize,将MinHeapTop从最小堆中移到最大堆,然后将num插入最小堆。
上面的插入情况会保证最大堆和最小堆的元素个数差小于1,中位数就只在最大堆和最小堆的顶部元素中产生:如果最大堆和最小堆的元素个数相等,则中位数为最大堆和最小堆的顶部元素的平均值;否则,中位数为元素个数多的那个堆的堆顶元素。
复杂度分析:
最差情况每次都要对堆做3次调整,复杂度为
c++代码:
// 这里忽略了arr为空和结果出现.5的情况// 优先队列就是对堆的封装int median_heap(const vector<int>& arr){ if(arr.size() == 1) return arr[0]; else if(arr.size() == 2) return (arr[0]+arr[1])/2; priority_queue<int> maxheap; priority_queue<int, vector<int>, greater<int>> minheap; maxheap.push(min(arr[0],arr[1])); minheap.push(max(arr[0],arr[1])); auto i=arr.begin()+2; for(;i!=arr.end();++i) { // 应放入maxheap if(*i < maxheap.top()) { if(maxheap.size() > minheap.size()) { minheap.push(maxheap.top()); maxheap.pop(); } maxheap.push(*i); } // 应放入minheap else if(*i > minheap.top()) { if(maxheap.size() < minheap.size()) { maxheap.push(minheap.top()); minheap.pop(); } minheap.push(*i); } // 放到哪个堆都行 else { if(maxheap.size() < minheap.size()) maxheap.push(*i); else minheap.push(*i); } } if(maxheap.size() > minheap.size()) return maxheap.top(); else if(maxheap.size() < minheap.size()) return minheap.top(); return (maxheap.top()+minheap.top())/2;}
参考
十道海量数据处理面试题与十个方法大总结
利用最大堆和最小堆在线寻找中位数
0 0
- 寻找中位数(分治+双堆)
- 利用最大堆和最小堆在线寻找中位数
- 寻找中位数
- 寻找中位数
- 寻找中位数
- 双堆维护数组中位数
- 双堆维护数组中位数
- 算法 双堆维护中位数
- 洛谷P1168 中位数(堆)
- SGU - 358 - Median of Medians (寻找中位数中的中位数)
- hdu3282 动态中位数(用堆实现)
- [TJOI2010]中位数(优先队列,堆)
- 关于寻找中位数
- 2:寻找中位数
- openjudge 寻找中位数
- 海量数据寻找中位数
- findMedianSortedArrays 寻找中位数
- HDU1157寻找中位数
- python简单小记
- hdu 5418 (状态压缩DP)
- 杭州电子科技大学acm--2005
- 1131 买水果【排列组合】大水坑!!
- Swift 防止快速连续点击"提交"按钮,造成多次提交
- 寻找中位数(分治+双堆)
- JavaScript 的 坑
- mysqlslap的使用记录
- 程序的机器级表示
- 正则表达式总结
- R语言:网页抓取之不同提取方法解析
- Java堆和栈的区别
- [Android]改变状态栏的颜色
- oracle用户下执行crontab -e报错