1. 程式人生 > >【LeetCode & 劍指offer刷題】查詢與排序題3:41 資料流中的中位數(295. Find Median from Data Stream)

【LeetCode & 劍指offer刷題】查詢與排序題3:41 資料流中的中位數(295. Find Median from Data Stream)

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)

41 資料流中的中位數

題目描述

如何得到一個數據流中的中位數?如果從資料流中讀出 奇數個數值,那麼 中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。   /* 1 2 3 4 [5]  + [6] 7 8 9 10 大頂堆 + 小頂堆 方法一:用兩個堆(stl中的priority_queue)
過程:用於一個大頂堆實現左邊容器,小頂堆實現右邊容器,根據左邊最大數與右邊最小數得到中位數     (1) 平均分配     (2) 還要保證大頂堆中所有資料小於小頂堆中元素,比較新資料與大頂堆和小頂堆堆頂元素就知道該放到哪裡 插入O(logn) 得到中位數O(1),空間複雜度O(n) */ class Solution { private
:     priority_queue < int > maxheap ; //stl中預設為大頂堆(聯絡預設的二叉搜尋樹, //根結點較左子樹大,中序遍歷從小到大,不同的是大頂堆根結點較左右子樹都大)     priority_queue < int , vector < int >, greater <
int >> minheap ; //小頂堆 public :     void Insert ( int num )     {         if ( maxheap . empty () || num < maxheap . top ()) maxheap . push ( num ); //如果新數屬於小的一半(左邊)         else minheap . push ( num );                 if ( maxheap . size () < minheap . size ()) //保持兩邊長度一致(左邊比右邊多一或者左右兩邊長度一樣)         {             maxheap . push ( minheap . top ());             minheap . pop ();         }         else if ( maxheap . size () > minheap . size () + 1 )         {             minheap . push ( maxheap . top ());             maxheap . pop ();         }                     }     double GetMedian ()     {        return ( maxheap . size ()> minheap . size ())? maxheap . top (): ( maxheap . top () + minheap . top ())* 0.5 ; //奇數時,返回中間元素,偶數時,返回中間兩個數的平均數,注意浮點數的處理       } };