剑指Offer-41:数据流中的中位数
2018-03-11 10:48
330 查看
题目:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。链接:
剑指Offer(第2版):P214思路标签:
算法:堆排序数据结构:最大堆、最小堆、vector
解答:
基于最大、最小堆的方法(时间复杂度:O(n)插入,O(1)查找)
其他如:排序数组、排序链表、二叉搜索树等方法与时间复杂度比较参见书中内容。因为我们寻找的是中位数,只要找到左边最大的数,右边最小的数,即可。所以可以分别使用最大最小堆来实现;
同时,因为是中位数,所以需要保证两个堆中的数据平衡;
为了实现平衡分配,可以在当前总数据数目是偶数时把新数据插入最小堆,奇数时插入最大堆;
以插入最大堆为例,如果当前插入的数据小于最大堆的最大值,那么将其插入到最大堆,并弹出最大堆的最大值,压入最小堆。这样就保证了最小堆中的数字都大于最大堆中的数字。同理插入最小堆的过程相对应。
class Solution { public: void Insert(int num) { if(((min.size()+max.size()) & 1) == 0){ if(max.size() > 0 && num < max[0]){ max.push_back(num); push_heap(max.begin(), max.end(), less<int>()); num = max[0]; pop_heap(max.begin(), max.end(), less<int>()); max.pop_back(); } min.push_back(num); push_heap(min.begin(), min.end(), greater<int>()); } else{ if(min.size() > 0 && num > min[0]){ min.push_back(num); push_heap(min.begin(), min.end(), greater<int>()); num = min[0]; pop_heap(min.begin(), min.end(), greater<int>()); min.pop_back(); } max.push_back(num); push_heap(max.begin(), max.end(), less<int>()); } } double GetMedian() { int size = max.size() + min.size(); if(size == 0) return 0; double median = 0; if((size & 1) == 1) median = (double)min[0]; else median = ((double)min[0] + (double)max[0]) /2; return median; } private: vector<int> min, max; };
C++相关
STL–heap概述https://www.cnblogs.com/likui360/p/6364896.html
相关文章推荐
- 【剑指offer】面试题41:数据流的中位数
- 【剑指offer】题64:数据流中的中位数
- 剑指offer面试题64 数据流中的中位数(Java实现)
- 剑指offer--数据流中的中位数
- 剑指Offer_63_数据流中的中位数
- 【剑指Offer-树】数据流中的中位数
- 【剑指Offer学习】【面试题64:数据流中的中位数】
- 剑指offer:数据流中的中位数
- [剑指Offer] 数据流中的中位数
- 剑指offer-数据流中的中位数
- 295. Find Median from Data Stream 剑指offer 数据流中的中位数
- 剑指offer-----数据流的中位数(java版)
- 剑指Offer——数据流中的中位数
- 剑指Offer--064-数据流中的中位数
- 剑指offer-面试题64-数据流中的中位数
- 剑指offer 64-数据流中的中位数
- 剑指offer——数据流中的中位数(好)(PriorityQueue,Comparator)
- 剑指offer——面试题64:数据流中的中位数
- 剑指offer-63题 数据流的中位数
- 剑指offer_数据流中的中位数