LeetCode480:滑动窗口中位数

目录

一、题目

二、示例

三、思路

四、代码


一、题目

中位数是有序序列最中间的那个数。如果序列的大小是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。

例如:

[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)

猜你喜欢

转载自blog.csdn.net/weixin_45666660/article/details/113586235