剑指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();
}
}
}

浙公网安备 33010602011771号