leetcode刷题笔记295题 数据流的中位数

leetcode刷题笔记295题 数据流的中位数

源地址:295. 数据流的中位数

问题描述:

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例:

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
进阶:

如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

//使用自大到小的优先队列down模拟大顶堆,使用自小到大的优先队列up模拟小顶堆,二者结合构成对顶堆
//保证down.size = up.size || up.size+1
//中位数即为down的top位置计算或up和down的top位置计算
import scala.collection.mutable.PriorityQueue
class MedianFinder() {

    /** initialize your data structure here. */
    val up = PriorityQueue.empty[Int](Ordering.by(n => n)).reverse
    val down = PriorityQueue.empty[Int](Ordering.by(n => n))

    def addNum(num: Int) {
        if (down.isEmpty == true || num <= down.head){
            down.enqueue(num)
            if (down.size > up.size + 1){
                up.enqueue(down.head)
                down.dequeue()
            }
        } else {
            up.enqueue(num)
            if (up.size > down.size){
                down.enqueue(up.head)
                up.dequeue()
            }
        }
    }

    def findMedian(): Double = {
        if ((up.size + down.size) % 2 == 1) return down.head
        else return (up.head + down.head)/2.0
    }

}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * var obj = new MedianFinder()
 * obj.addNum(num)
 * var param_2 = obj.findMedian()
 */
posted @ 2020-11-19 12:09  ganshuoos  阅读(87)  评论(0编辑  收藏  举报