1. 程式人生 > 其它 >Leetcode每日一題:480. 滑動視窗中位數

Leetcode每日一題:480. 滑動視窗中位數

技術標籤:leetcode練習leetcode演算法python

目錄

問題描述

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

例如:

[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]。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sliding-window-median
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

思路分析及程式碼實現

這道題我一開始的做法就是暴力解,首先將視窗定在一開始前k個數,然後排序求出中位數並新增到ans中,然後右邊界+1,左邊界+1,更新視窗,再重複上面操作

程式碼:

import math
class Solution:
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        n = len(nums)
        ans = []
        window = nums[:k]
        
        while right < n:
        	window = nums[left:right+1]
        	window.sort()
            if k % 2 != 0:
            	mid =
(k-1) // 2 ans.append(window[mid]) else: mid1 = (k-1) // 2 mid2 = math.ceil((k-1) / 2) ans.append((window[mid1] + window[mid2]) / 2) right += 1 left += 1 return ans

在這裡插入圖片描述
看到這個時間複雜度,我一陣。。。。。

看了一下題解中的做法,發現很多使用二分來做的,然後學到了一個二分的模組bisect
第二種方法就是隻用一個視窗,然後每次求出中位數後,刪除視窗中的i值,並用二分的方法新增j

import bisect
import math
class Solution:
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        n = len(nums)
        ans = []
        window = nums[:k]
        window.sort()
        if k % 2 != 0:
            mid = (k - 1) // 2
            ans.append(window[mid])
        else:
            mid1 = (k - 1) // 2
            mid2 = math.ceil((k - 1) / 2)
            ans.append((window[mid1] + window[mid2]) / 2)
        for i, j in zip(nums[:-k], nums[k:]):
                window.remove(i)
                bisect.insort_left(window, j)
                if k % 2 != 0:
                    mid = (k-1) // 2
                    ans.append(window[mid])
                else:
                    mid1 = (k-1) // 2
                    mid2 = math.ceil((k-1) / 2)
                    ans.append((window[mid1] + window[mid2]) / 2)
        return ans

在這裡插入圖片描述
然後時間提高了一點。。。。。。