直接回答:用单调递减双端队列。队列里存下标,维护规则:新元素入队前,从队尾弹出所有比它小的元素(它们再也不可能成为最大值);队首元素滑出窗口范围时弹出。这样队首始终是当前窗口最大值的下标,每个元素恰好进出队一次,总时间 O(n)、空间 O(k)。

展开解析:核心洞察是「后来者居上」:若 a 在 b 之前且 a < b,那么 a 在任何同时包含两者的窗口里都不可能是最大值,可以永久丢弃——队列只需保留单调递减的候选链。这就是单调队列与单调栈的共同思想(栈处理一维方向、队列处理带窗口过期)。对比朴素 O(nk) 和堆 O(n log k):堆不能高效删除滑出窗口的任意元素,需要懒删除技巧。变体与追问:滑动窗口最小值(改比较方向)、两者组合可解「窗口最大值减最小值不超过 limit 的最长子数组」;单调栈族题还有每日温度、下一个更大元素(环形数组用取模扫两遍)。

示例

from collections import deque

def max_sliding_window(nums, k):
    q = deque()
    res = []
    for i, x in enumerate(nums):
        while q and nums[q[-1]] < x:
            q.pop()                    # 比新元素小的永无出头之日
        q.append(i)
        if q[0] <= i - k:
            q.popleft()                # 滑出窗口
        if i >= k - 1:
            res.append(nums[q[0]])
    return res