剑指 Offer 41. 数据流中的中位数
题目:
思路:
求中位数,使用最大堆和最小堆
- 都为空或一个为空,应该怎么向两个堆里放值
- 都不为空该怎么放入
- 放完后判断size,使得size的差距不要超过1,这样就可以计算中位数
注意:
此算法中不能使用BigDecimal
注意等号的位置(上次刷这道题还是1月前,今天看发现是等号写错了,导致过不了)
题解:
/** initialize your data structure here. */
public MedianFinder() {
this.minHeap = new PriorityQueue<>();
this.maxHeap = new PriorityQueue<>((a, b) -> (b - a));
}
private Queue<Integer> minHeap;
private Queue<Integer> maxHeap;
/**
* 中位数,维持一个最大堆和最小堆,大于等于最小的放入,小于等于最大的放入,那个size小,放到哪个里面
* @param num
*/
public void addNum(int num) {
if (maxHeap.isEmpty()) {
maxHeap.offer(num);
return;
}
if (minHeap.isEmpty()) {
if (num >= maxHeap.peek()) {
minHeap.offer(num);
} else {
maxHeap.offer(num);
minHeap.offer(maxHeap.poll());
}
return;
}
// 比较数据的大小
if (num > minHeap.peek() ) {
minHeap.offer(num);
}
if (num < maxHeap.peek()) {
maxHeap.offer(num);
}
if (num <= minHeap.peek() && num >= maxHeap.peek()) {
maxHeap.offer(num);
}
// 每次放完数据都进行size判断,使得两者的差不超过1
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.offer(maxHeap.poll());
}
if (minHeap.size() > maxHeap.size() + 1) {
maxHeap.offer(maxHeap.poll());
}
}
public double findMedian() {
if (minHeap.size() == maxHeap.size()) {
return new BigDecimal(minHeap.peek()).add(new BigDecimal(maxHeap.peek())).divide(new BigDecimal(2)).doubleValue();
}
if (minHeap.size() > maxHeap.size()) {
return minHeap.peek().doubleValue();
}else{
return maxHeap.peek().doubleValue();
}
}