牛客网刷题之数据流中的中位数
来源:互联网 发布:python 全文搜索引擎 编辑:程序博客网 时间:2024/06/08 11:34
题目描述:
解题思路:
这种题属于在线算法类型的,有一个经典的问题就是在一亿个数中取出前100个最小数,显然,可以建立一个数量为100的最小堆来维护。类似的,我们这里也可以借鉴这种方法,但由于新增加的数可能会覆盖掉原先丢掉的数,所以我们还需要建立一个最大堆来进行维护。前面部分建立最大堆,后面部分建立最小堆。
题目是求中位数,所以我们只需要位于中间的两个数就可以了,当元素个数为奇数个时可以看成这两个数一样。中位数在前半部分它是最大的,右半部分是最小的。我们只要始终知道前半部分数里的最大的那个数,后半部分里那个最小的数就可以了。为了实现平均分配,可以在数据的总数目是偶数时把新数据插入到最小堆中,否则插入最大堆中。
另一个问题是保持最大堆的所有数据都小于最小堆中的数据。如果插入一个数使得总数目和为偶数,根据之前的原则应该插入最小堆中,但是新插入的元素可能比最大堆中的元素小怎么办?这就违反了最小堆的数据一定大于最大堆得原则。实际上这里插入的元素应该是新元素和最大堆中所有元素的最大值,最大堆正好有返回一个最大值的作用,所以新插入的元素先插入最大堆,然后取出最大值再插入最小堆中。如果插入元素使得数据总数目和为奇数,处理方法类似。
这里还需要注意的是PriorityQueue默认是小顶堆,实现大顶堆,需要反转默认排序器。
题解:
private int count = 0; private PriorityQueue<Integer> minHeap = new PriorityQueue<>(); private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(15, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); public void Insert(Integer num) { if ((count & 1) == 0) { maxHeap.offer(num); int maxNumInmaxHeap = maxHeap.poll(); minHeap.offer(maxNumInmaxHeap); }else{ minHeap.offer(num); int minNumInminHeap = minHeap.poll(); maxHeap.offer(minNumInminHeap); } count++; } public Double GetMedian() { if ((count & 1) == 0) { return new Double((minHeap.peek() + maxHeap.peek())) / 2; } else { return new Double(minHeap.peek()); } }
ac结果:
0 0
- 牛客网刷题之数据流中的中位数
- 剑指offer(六十三)之数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 求数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 【63】数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- Q64:数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 一个封装android开发常用控件的库
- Dubbo2.3.2的服务停止脚本stop.sh源码
- js原生代码实现数据双向绑定
- 堆和栈的区别(内存和数据结构)
- Leetcode 98. Validate Binary Search Tree (Medium) (cpp)
- 牛客网刷题之数据流中的中位数
- Java并发编程(Java Concurrency)(12)- Java 同步代码块(Java Synchronized Blocks)
- 在sklearn中使用DataFrame的一些问题(训练集与测试集列顺序问题)
- cmd下查看java字节码
- java 正则表达式 特殊构造(非捕获)理解 (2)
- CentOS6.6将/var移到新的分区
- 图的遍历——C语言
- Error: Expected resource of type id [ResourceType]的解决办法
- windows 连接Ubuntu 中HDFS的权限错误:Permission denied