1. 程式人生 > 實用技巧 >leetcode刷題筆記295題 資料流的中位數

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()
 */