随时找到数据流中的中位数
題目: 有一個源源不斷地吐出整數的數據流,假設你有足夠的空間來保存吐出的數。請設計一個名叫MedianHolder的結構,MedianHolder可以隨時取得之前吐出所有數的中位數。
要求: 如果MedianHolder已經保存了吐出的N個數,那么任意時刻將一個新數加入到MedianHolder的過程,其時間復雜度O(logN)。
取得已經吐出的N個數整體的中位數的過程,時間復雜度O(1)。
基本思路:使用兩個堆結構,一個大根堆,一個小根堆。將接收的所有數的較小的一半放入大根堆,將接收的較大的一半放入小根堆。如果接收的個數為奇數,中位數就是小根堆和大根堆中元素數量多的那個堆的堆頂,比如吐出的數是6,1,3,0,9,8,7,小根堆中存放6,7,8,9,大根堆存放0,1,3,小根堆的元素個數多,它的堆頂就是該序列的中位數,即6;如果接收的個數是偶數,中位數就是兩個堆頂相加除以2。
每次接收到一個數,都要正確選擇放入哪個堆,小于小根堆堆頂的都放入大根堆,否則放入小根堆。如果出現一個堆的元素個數比另一個堆的元素多兩個的情況,將前者的堆頂彈出添加到后者中,并重新調整兩個堆。總之要始終保持兩個堆元素個數的差值不大于1。
這樣隨時都可以知道已經吐出的所有數處于中間位置的兩個數是什么,取得中位數的操作時間復雜度為O(1),同時根據堆的性質,向堆中添加一個新數,并且調整堆的代價為O(logN)。然而題目有一個很重要的限制“任意時刻將一個新數加入到MedianHolder的過程,其時間復雜度O(logN)”
?
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的随时找到数据流中的中位数的全部內容,希望文章能夠幫你解決所遇到的問題。