1. 程式人生 > 其它 >LeetCode480:滑動視窗中位數

LeetCode480:滑動視窗中位數

技術標籤:LeetCode演算法資料結構pythonleetcode二分查詢

目錄

一、題目

二、示例

三、思路

四、程式碼


一、題目

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

例如:

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

三、思路

1、暴力法

暴力法很直接且易懂。

tmp 陣列為我們視窗中的數字組成每次對 tmp 進行排序,利用python中的內建函式sort()函式

,找出中位數即可。

2、二分法

python中的 bisect 模組包含兩個主要函式, bisect 和 insort兩個函式都利用二分查詢演算法來在有序序列中查詢或插入元素。

因此我們在排序上進行優化。

這裡我們用到了bisect_left() 函式和insort() 函式 :

bisect_left函式是新元素會被放置於它相等的元素的前面;

insort(seq, item) 把變數 item 插入到序列 seq 中,並能保持 seq 的升序順序。

最後,找出中位數即可。

四、程式碼

1、

class Solution:
    def medianSlidingWindow(self, nums, k: int):
        """
        :param nums: List[int]
        :param k: int
        :return: List[float]
        """
        ans = []
        left, right = 0, k - 1
        for right in range(k - 1, len(nums)):
            tmp = nums[left: right + 1]
            tmp.sort()
            if k % 2 == 0:
                ans.append((tmp[(k + 1) // 2 - 1] + tmp[(k + 1) // 2]) / 2)
                left += 1
            else:
                ans.append(tmp[(k + 1) // 2 - 1])
                left += 1
        return ans


if __name__ == '__main__':
    nums = [1, 3, -1, -3, 5, 3, 6, 7]
    k = 3
    s = Solution()
    ans = s.medianSlidingWindow(nums, k)
    print(ans)

2、

class Solution:
    def medianSlidingWindow(self, nums, k: int):
        import bisect
        ans = []
        tmp = []
        left, right = 0, k - 1
        for right in range(len(nums)):
            bisect.insort(tmp, nums[right])  # 利用二分查詢演算法來在有序序列中插入元素
            if len(tmp) > k:
                tmp.pop(bisect.bisect_left(tmp, nums[left]))  # 利用二分查詢演算法來在有序序列中查詢元素
                left += 1
            if len(tmp) == k:
                if k % 2 == 0:
                    ans.append((tmp[(k + 1) // 2 - 1] + tmp[(k + 1) // 2]) / 2)
                else:
                    ans.append(tmp[(k + 1) // 2 - 1])
        return ans

if __name__ == '__main__':
    nums = [1, 3, -1, -3, 5, 3, 6, 7]
    k = 3
    s = Solution()
    ans = s.medianSlidingWindow(nums, k)
    print(ans)