leetcode480 滑動視窗中位數

2021-10-03 10:53:25 字數 2050 閱讀 7960

中位數是有序序列最中間的那個數。如果序列的大小是偶數,則沒有最中間的數;此時中位數是最中間的兩個數的平均數。

例如:[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 所以,還需要兩個操作,插入和刪除。由於堆的特點 只能訪問堆頂的元素。所以,如果刪除的元素,不在堆頂的話,就只能延遲刪除。為了查詢的時間複雜度,只能使用堆這種結構來維護資料的有序。插入的話,如果細...