📌  相关文章
📜  查找给定数组中每个窗口大小的最大值(1)

📅  最后修改于: 2023-12-03 14:55:35.947000             🧑  作者: Mango

查找给定数组中每个窗口大小的最大值

当我们需要在一个数组中找到每个窗口的最大值时,我们可以使用滑动窗口的方法。滑动窗口是一个固定大小的窗口,可以在数组上从左到右进行滑动,每次在窗口中找到最大值,并将其存储在一个结果数组中。下面是一个使用滑动窗口查找给定数组中每个窗口大小的最大值的实现。

实现过程
  • 定义一个结果数组res,长度为原始数组长度减去窗口大小再加一
  • 定义一个双端队列deq用于存储可能成为最大值的元素的下标
  • 遍历原始数组,对于每个元素做以下操作
    • 如果队列不为空且队尾元素小于当前元素,则将队尾元素弹出
    • 将当前元素下标添加到队尾
    • 如果队头元素的下标已经不在当前窗口中,则将其弹出
    • 如果当前下标大于等于窗口大小减一,则将队头元素作为当前窗口的最大值添加到结果数组中

代码实现如下:

def maxSlidingWindow(nums, k):
    res = []
    deq = collections.deque()
    for i, n in enumerate(nums):
        while deq and nums[deq[-1]] < n:
            deq.pop()
        deq.append(i)
        if deq[0] <= i - k:
            deq.popleft()
        if i >= k - 1:
            res.append(nums[deq[0]])
    return res
时间复杂度

由于每个元素最多被添加和删除一次,因此该算法的时间复杂度为O(n)。

空间复杂度

由于存储了双端队列和结果数组,因此该算法的空间复杂度为O(n)。

使用示例
nums = [1,3,-1,-3,5,3,6,7]
k = 3
print(maxSlidingWindow(nums, k)) # [3,3,5,5,6,7]
优化

可以使用堆来维护窗口中的最大值,但是将元素从堆中删除需要O(k)时间复杂度,因此总时间复杂度为O(nk)。该算法的优点是可以处理动态数据流,而不需要维护整个数组。