leetcode 480 滑動視窗中位數

2021-10-18 22:13:25 字數 3127 閱讀 7604

目錄

一、題目內容

二、解題思路

三、**

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

例如:

[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 以內的答案將被視作正確答案。

1.暴力法:每次取k個數,排序後得到中位數;

2.二分插入排序和二分查詢法,維護乙個長度為k的滑動視窗,每次移動都需要進行二分插入排序演算法插入右端的元素,然後利用二分查詢將左端的數pop出去,然後得到中位數。可以利用bisect求解更快。

class solution:

def medianslidingwindow(self, nums: list, k: int) -> list:

ans =

for i in range(len(nums) - k + 1):

tmp = sorted(nums[i:i+k])

if k % 2 == 0:

center = (tmp[k // 2] + tmp[k // 2 - 1]) / 2

else:

center = tmp[k // 2]

return ans

def medianslidingwindow1(self, nums, k: int):

def find_index_in_list(a, x, left=0, right=none):

if right is none:

right = len(a)

while left < right:

mid = (left + right) // 2

if a[mid] < x:

left = mid + 1

else:

right = mid

return left

def insert_x_in_list(a, x, left=0, right=none):

if right is none:

right = len(a)

while left < right:

mid = (left + right) // 2

if a[mid] < x:

left = mid + 1

else:

right = mid

if len(a) == 1:

a[0] = x

else:

i = len(a) - 2

if i >= left:

a[left + 1:i + 2] = a[left:i + 1]

a[left] = x

ans =

tmp =

left, right = 0, k - 1

for right in range(len(nums)):

insert_x_in_list(tmp, nums[right])

while len(tmp) > k:

tmp.pop(find_index_in_list(tmp, nums[left]))

left += 1

if len(tmp) == k:

if k % 2 == 0:

else:

return ans

def medianslidingwindow2(self, nums, k: int):

import bisect

ans =

tmp =

left, right = 0, k - 1

for right in range(len(nums)):

bisect.insort(tmp, nums[right]) # 利用二分查詢演算法來在有序序列中插入元素

while len(tmp) > k:

tmp.pop(bisect.bisect_left(tmp, nums[left])) # 利用二分查詢演算法來在有序序列中查詢元素

left += 1

if len(tmp) == k:

if k % 2 == 0:

else:

return ans

if __name__ == '__main__':

s = solution()

nums = [1, 3, -1, -3, 5, 3, 6, 7]

k = 3

ans = s.medianslidingwindow1(nums, k)

print(ans)

leetcode480 滑動視窗中位數

中位數是有序序列最中間的那個數。如果序列的大小是偶數,則沒有最中間的數 此時中位數是最中間的兩個數的平均數。例如 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 個數,每次視窗向右移動 1 位。你的任...

leetcode 480 滑動視窗中位數

基本思路是具備的,利用兩個堆,這樣我們就可以直接得到,中位數相關的兩個元素。查詢的複雜度可以控制在o 1 所以,還需要兩個操作,插入和刪除。由於堆的特點 只能訪問堆頂的元素。所以,如果刪除的元素,不在堆頂的話,就只能延遲刪除。為了查詢的時間複雜度,只能使用堆這種結構來維護資料的有序。插入的話,如果細...