剑指offer 54. 数据流中的中位数-java
acwing 54. 数据流中的中位数
原题链接
如何得到一个数据流中的中位数?
如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
数据范围
数据流中读入的数据总数 [1,1000]。
代码案例:输入:1, 2, 3, 4
输出:1,1.5,2,2.5
解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。
题解
暴力做法1
class Solution {
List<Integer> a = new ArrayList<>();
public void insert(Integer num) {
a.add(num);
}
public Double getMedian() {
double res ;
int k = a.size();
Collections.sort(a);
if(k % 2 == 0){//偶数
int aa = a.size() / 2 ;
int bb = a.size() /2 - 1 ;
res = (a.get(aa) + a.get(bb) )/2.0 ;
}else{
int cc = a.size() /2 ;
res = a.get(cc);
}
return res ;
}
}
直接使用PriorityQueue构造大小堆,大顶堆放小于中位数的集合,小顶堆放大于中位数的集合,
取得时候,如果是奇数,就取前半部分的最大数,如果是偶数,就取前半部分的最大数和后半部分的最小数的平均数
往里放的时候,如果总数是偶数,就往前放,需要现在后半部分过滤一遍选出后半部分最小的数往前放,奇数同理
class Solution {
// 大根堆,记录小于等于中位数
PriorityQueue<Integer> smaller = new PriorityQueue<>((a, b) -> b - a);
// 小根堆,记录大于中位数
PriorityQueue<Integer> larger = new PriorityQueue<>((a, b) -> a - b);
// 保证当元素总数为偶数时,smaller 和 larger 中的元素个数相等
// 当元素总数为奇数时,smaller 的元素个数比 larger 多一个
public void insert(Integer num) {
// 如果 smaller 为空,由于我们的规定,此时 larger 也一定为空
// 说明当前数字是数据流的第一个数字,插入到 smaller 中
if (smaller.isEmpty() || num <= smaller.peek()) {
smaller.offer(num);
if (smaller.size() > larger.size() + 1) {
larger.offer(smaller.poll());
}
} else {
larger.offer(num);
if (larger.size() > smaller.size()) {
smaller.offer(larger.poll());
}
}
}
public Double getMedian() {
if (smaller.size() == larger.size()) {//偶数
return (smaller.peek() + larger.peek()) / 2.0;
} else {//奇数
return (double) smaller.peek();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)