如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
- 暴力解法,存进数组,求中位数时排序再取
时间复杂度:Insert()为O(1), GetMedian()为O(nlogn)
空间复杂度:O(n) - 插入排序,插入的时候维持顺序,中位数直接取
时间复杂度:Insert()为O(n), GetMedian()为O(1)
空间复杂度:O(n) - 堆,维护左边最大堆,右边最小堆,使用优先队列PriorityQueue
时间复杂度:Insert()为O(logn), GetMedian()为O(1)
空间复杂度:O(n)
import java.util.*;
public class Solution {
private int cnt = 0;
private PriorityQueue<Integer> low = new PriorityQueue<>();
private PriorityQueue<Integer> high = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
public void Insert(Integer num) {
cnt++;
if ((cnt & 1) == 1) {
if (!low.isEmpty() && num > low.peek()) {
low.offer(num);
num = low.poll();
}
high.offer(num);
} else {
if (!high.isEmpty() && num < high.peek()) {
high.offer(num);
num = high.poll();
}
low.offer(num);
}
}
public Double GetMedian() {
double res = 0;
if ((cnt & 1) == 1) {
res = high.peek();
} else {
res = (high.peek() + low.peek()) / 2.0;
}
return res;
}
}