牛客网刷题笔记--剑指offer(数据流中的中位数)
2016-08-24 10:46
387 查看
题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
剑指offer给出的思路是:
用两个堆,一个大顶堆,一个小顶堆,若两个堆的元素个数之和为偶数,那中位数为两个堆顶元素值的平均,若个数和为基数,则中位数为小顶堆的顶。
逻辑为:1 先判断两个堆的元素个数是否相等,若想等,则将数字插入到小顶堆中
1.1 再对插入的数字做一个判断,若该数字比大顶堆的最大值还要小,那在小顶堆的中位数可能要改变了,这个值会编程大顶堆的最大值,因此,取出大顶堆的最大值,插入到小顶堆中。
2 若两个堆的元素个数不相等,也就是说现在的中位数在小顶堆上,这次需要将被插入的数字插入到大顶堆中
2.1 若插入的数字大于小顶堆的最小值,那大顶堆的最大值应该是包含该数字的小顶堆的最小值,找到小顶堆的最小值,取出插入到大顶堆中。
上述为插入操作。
对于取中位数,那就方便多了。做一次判断,如果两个堆的元素个数和为奇数,中位数为小顶堆的最小值;若两个堆的元素个数为偶数,中位数为两个堆堆顶元素值的平均值。
代码粘贴如下:
这里的make_heap()函数是用来生成堆的,第三个参数less和greater分别表示生成大顶堆和小顶堆,堆顶为数组下标为零的元素。
pop_heap()是将数组零下标元素和数组最后一个元素进行交换,忽略最后一个元素,对剩余的元素进行调整,生成堆。所以还需要用pop_back()函数来删除掉不需要的元素。
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
剑指offer给出的思路是:
用两个堆,一个大顶堆,一个小顶堆,若两个堆的元素个数之和为偶数,那中位数为两个堆顶元素值的平均,若个数和为基数,则中位数为小顶堆的顶。
逻辑为:1 先判断两个堆的元素个数是否相等,若想等,则将数字插入到小顶堆中
1.1 再对插入的数字做一个判断,若该数字比大顶堆的最大值还要小,那在小顶堆的中位数可能要改变了,这个值会编程大顶堆的最大值,因此,取出大顶堆的最大值,插入到小顶堆中。
2 若两个堆的元素个数不相等,也就是说现在的中位数在小顶堆上,这次需要将被插入的数字插入到大顶堆中
2.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); make_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); make_heap(min.begin(), min.end(), greater<int> ()); } else { if (min.size() > 0 && num > min[0]) { min.push_back(num); make_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); make_heap(max.begin(), max.end(), less<int> ()); } } double GetMedian() { int size = min.size() + max.size(); if (size == 0) return 0.0; double median = 0; if ((size & 1) == 1) median = min[0]; else median = (max[0] + min[0]) / 2.0; return median; } private: vector<int> min; vector<int> max; };
这里的make_heap()函数是用来生成堆的,第三个参数less和greater分别表示生成大顶堆和小顶堆,堆顶为数组下标为零的元素。
pop_heap()是将数组零下标元素和数组最后一个元素进行交换,忽略最后一个元素,对剩余的元素进行调整,生成堆。所以还需要用pop_back()函数来删除掉不需要的元素。
相关文章推荐
- 《剑指Offer》学习笔记--面试题64:数据流中的中位数
- 剑指offer系列之六十二:数据流中的中位数
- 剑指offer(65):获取数据流中的中位数
- 《剑指offer》刷题笔记(树):数据流中的中位数
- 剑指offer:数据流中的中位数
- 剑指Offer——数据流中的中位数
- 二叉堆,堆排序,STL优先队列的底层实现,剑指offer数据流中的中位数
- 剑指offer——数据流中的中位数
- 剑指offer 面试题64 数据流的中位数
- 剑指offer--面试题64:数据流中的中位数
- 剑指offer—数据流中的中位数
- 剑指offer——数据流中的中位数___ (堆应用实例)
- 牛客网 数据流中的中位数(用两个堆实现)
- 《剑指offer》面试题64 数据流中的中位数
- 剑指Offer(41)数据流的中位数
- 剑指Offer——数据流中的中位数
- 剑指offer面试题[64]-数据流中的中位数
- 《剑指offer》-数据流中的中位数
- 《剑指offer》:[64]数据流中的中位数
- 《剑指offer》数据流中的中位数