中位數是有序序列最中間的那個數。如果序列的大小是偶數,則沒有最中間的數;此時中位數是最中間的兩個數的平均數。
例如:[2,3,4],中位數是 3
[2,3],中位數是 (2 + 3) / 2 = 2.5
給出乙個陣列 nums,有乙個大小為 k 的視窗從最左端滑動到最右端。視窗中有 k 個數,每次視窗向右移動 1 位。你的任務是找出每次視窗移動後得到的新視窗中元素的中位數,並輸出由它們組成的陣列。
示例:給出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。
視窗位置 中位數
[1 3 -1] -3 5 3 6 7 1
1 [3 -1 -3] 5 3 6 7 -1
1 3 [-1 -3 5] 3 6 7 -1
1 3 -1 [-3 5 3] 6 7 3
1 3 -1 -3 [5 3 6] 7 5
1 3 -1 -3 5 [3 6 7] 6
因此,返回該滑動視窗的中位數陣列 [1,-1,-1,3,5,6]。
你可以假設 k 始終有效,即:k 始終小於輸入的非空陣列的元素個數。
與真實值誤差在 10 ^ -5 以內的答案將被視作正確答案。
思路:
抱著本題和 「資料流中位數」 一定有不可分割關係的思想,還真的按那道題的解法嗑出了本題。
因為本題要刪數和加數,我就想是否可以鍊錶?鍊錶實現刪數很簡單,加數我則需要二分其位置,那我需要multiset來維護這樣乙個數列,貌似不輕鬆。
那考慮對頂堆的寫法,維護兩個堆, len
1=1到
(k+1
)/
2len1 =1到(k+1)/2
len1=1
到(k+
1)/2
, 乙個數len
2=(k
+1)/
2+1到
klen2 = (k+1)/2+1到k
len2=(
k+1)
/2+1
到k當加數的時候直接加就好了,需要刪數的時候,優先佇列怎麼刪數??那我得用乙個更優秀的資料結構multiset。不過仔細一想,我一定要刪掉這個數嗎?
其實我只要保證堆頂的數不是需要刪的數就好了,堆下面有需要刪的數不影響中位數,而我只需要len1++或者len2++就可以保證這個數在堆裡面而不影響中位數
class
solution
if(q2.
size()
> i +1-
(i +1+
1)/2
)}if(k %2==
1)else
int len1 =
(k +1)
/2,len2 = k -
(k +1)
/2;for
(int i = k;i < n;i++
)else
while
(q1.
size()
&& mp1[q1.
top()]
)while
(q2.
size()
&& mp2[
-q2.
top()]
)
x1 = q1.
top();
if(nums[i]
<= x1)q1.
push
(nums[i]);
else q2.
push
(-nums[i]);
if(q1.
size()
> len1)
if(q2.
size()
> len2)
while
(q1.
size()
&& mp1[q1.
top()]
)while
(q2.
size()
&& mp2[
-q2.
top()]
)if(k %2==
1)else
}return ans;}}
;
leetcode 480 滑動視窗中位數
中位數是有序序列最中間的那個數。如果序列的大小是偶數,則沒有最中間的數 此時中位數是最中間的兩個數的平均數。例如 2,3,4 中位數是 3 2,3 中位數是 2 3 2 2.5 給你乙個陣列 nums,有乙個大小為 k 的視窗從最左端滑動到最右端。視窗中有 k 個數,每次視窗向右移動 1 位。你的任...
leetcode 480 滑動視窗中位數
目錄 一 題目內容 二 解題思路 三 中位數是有序序列最中間的那個數。如果序列的長度是偶數,則沒有最中間的數 此時中位數是最中間的兩個數的平均數。例如 2,3,4 中位數是 3 2,3 中位數是 2 3 2 2.5 給你乙個陣列 nums,有乙個長度為 k 的視窗從最左端滑動到最右端。視窗中有 k ...
leetcode 480 滑動視窗中位數
基本思路是具備的,利用兩個堆,這樣我們就可以直接得到,中位數相關的兩個元素。查詢的複雜度可以控制在o 1 所以,還需要兩個操作,插入和刪除。由於堆的特點 只能訪問堆頂的元素。所以,如果刪除的元素,不在堆頂的話,就只能延遲刪除。為了查詢的時間複雜度,只能使用堆這種結構來維護資料的有序。插入的話,如果細...