# 0480. 滑动窗口中位数

### 题目地址(480. 滑动窗口中位数)

<https://leetcode-cn.com/problems/sliding-window-median/>

### 题目描述

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

例如：

[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 以内的答案将被视作正确答案。
```

### 前置知识

* [二分查找](/leetcode-solution/91/binary-search.md)

### 公司

* 暂无

### 思路

每次窗口移动都伴随左侧移除一个，右侧添加一个。而中位数是排序之后的中间数字。因此我们的思路是维护一个大小为 k 的有序数组，这个有序数组就是窗口内的数组**排序之后**的结果。

而在一个有序数组添加和移除数字，可以使用二分法在 $O(logk)$ 的时间找到，并在 $O(k)$ 的时间完成删除， $O(1)$ 的时间完成插入。因此总的时间复杂度为 $n\*k$。

### 关键点

* 滑动窗口 + 二分

### 代码

* 语言支持：Python3

Python3 Code:

```python

class Solution:
    def medianSlidingWindow(self, A: List[int], k: int) -> List[float]:
        ans = []
        win = []

        for i, a in enumerate(A):
            bisect.insort(win, a)
            if i >= k:
                win.pop(bisect.bisect_left(win, A[i - k]))
            if i >= k - 1:
                if k & 1:
                    median = win[k // 2]
                else:
                    median = (win[k // 2] + win[k // 2 - 1]) / 2
                ans.append(median)
        return ans


```

**复杂度分析**

令 n 为数组长度。

* 时间复杂度：数组插入的时间复杂度为 $O(k)$, 因此总的时间复杂度为 $O(n \* k)$
* 空间复杂度：使用了大小为 k 的数组，因此空间复杂度为 $O(k)$

> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。

力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/)，这样就会第一时间收到我的动态啦\~

以上就是本文的全部内容了。大家对此有何看法，欢迎给我留言，我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库：<https://github.com/azl397985856/leetcode> 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。

关注公众号力扣加加，努力用清晰直白的语言还原解题思路，并且有大量图解，手把手教你识别套路，高效刷题。

![](https://p.ipic.vip/kx3tot.jpg)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://leetcode-solution-leetcode-pp.gitbook.io/leetcode-solution/hard/480.sliding-window-median.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
