資料流的中位數

2022-05-15 08:27:38 字數 1595 閱讀 3440

問題定義: 不斷有數字過來,問在當前所有數字中的中位數是多少

優先佇列--堆

我們可以用乙個大根堆和乙個小根堆分別維護乙個有序數,使得小根堆的所有數字都大於大根堆,這就要求小根堆的堆頂要大於等於大根堆的堆頂。

為了求得中位數,我們需要小根堆和大根堆的數字個數相等或相差一。

我們可以用優先佇列實現如下:

priority_queue,greater>l; //小根堆

priority_queueg; //大根堆

void add(int num)

else

}int ask()

應用 lcp24

小釦在秋日市集入口處發現了乙個數字遊戲。主辦方共有 n 個計數器,計數器編號為 0 ~ n-1。每個計數器上分別顯示了乙個數字,小釦按計數器編號公升序將所顯示的數字記於陣列 nums。每個計數器上有兩個按鈕,分別可以實現將顯示數字加一或減一。小釦每一次操作可以選擇乙個計數器,按下加一或減一按鈕。

主辦方請小釦回答出乙個長度為 n 的陣列,第 i 個元素(0 <= i < n)表示將 0~i 號計數器 初始 所示數字操作成滿足所有條件 nums[a]+1 == nums[a+1],(0 <= a < i) 的最小運算元。回答正確方可進入秋日市集。

由於答案可能很大,請將每個最小運算元對 1,000,000,007 取餘。

思路我們對等式做一點小小的轉化:nums[a]-a==nums[a+1]-(a+1),所以我們最終要得到的是所有的nums[i]-i的數字都相等。那麼這個數很顯然應該是這些數字的中位數

那麼我們可以維護資料流的中位數,但是這樣還要依此算下每個位置的代價(與中位數的距離),因此我們不妨直接維護兩個堆中所有數字的和。

用l表示小根堆,r表示大根堆,讓r的元素與l相等或多一,那麼

當有奇數個數字時,代價是l元素的和sum[l]-nm+(n+1)m-sum[r]=sum[l]-sum[r]+m

當有偶數個數字時,代價是l元素的和sum[l]-nm+(n)m-sum[r]=sum[l]-sum[r]

**如下:

class solution ;

for(int i=0;ig; //大根堆

priority_queue,greater>l; //小根堆

vectorans;

l.push(max(nums[0],nums[1]));

g.push(min(nums[0],nums[1]));

ll sum0=g.top(),sum1=l.top();

ans.push_back(0);

ans.push_back(sum1-sum0);

for(int i=2;il.top())

else if(nums[i]<=g.top())

// cout

else if(l.size()==g.size()+1)

//cout

ans.push_back(val%mod);

}return ans;

}};

資料流的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用insert 方法讀取資料流,使用getmedian 方法獲取當前讀取資料的中位數。coding utf ...

資料流的中位數

資料流的中位數 中位數是有序列表中間的數。如果列表長度是偶數,中位數則是中間兩個數的平均值。例如,2,3,4 的中位數是 3 2,3 的中位數是 2 3 2 2.5 設計乙個支援以下兩種操作的資料結構 示例 addnum 1 addnum 2 findmedian 1.5 addnum 3 find...

資料流中的中位數

資料流中的中位數 如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。解題思路 維護乙個大堆和乙個小堆,大堆表示序列前一半數,小堆表示序列後一半數,保持兩個堆的元素個...