数据结构与算法之 leetcode 队列滑动窗口最大值优化 单调队列

数据结构与算法阿木 发布于 4 天前 1 次阅读


队列滑动窗口最大值优化(单调队列)在LeetCode中的应用

在数据结构与算法的学习过程中,滑动窗口问题是一个经典且具有挑战性的问题。它要求我们在一个数据序列中,维护一个大小固定的窗口,并计算窗口内元素的最大值或最小值。在LeetCode中,这类问题经常出现,例如“滑动窗口最大值”问题。本文将围绕这一主题,探讨如何使用单调队列优化滑动窗口最大值问题的求解过程。

概述

滑动窗口最大值问题通常描述如下:给定一个数组`nums`和一个整数`k`,找出所有大小为`k`的连续子数组中的最大值。例如,对于`nums = [1,3,-1,-3,5,3,6,7]`和`k = 3`,输出应为`[3,3,5,5,6,7]`。

传统的解法是使用双端队列(deque)来维护窗口内的最大值,但这种方法的时间复杂度较高。单调队列是一种优化方法,它可以在O(1)时间内完成元素的入队和出队操作,从而将整个问题的求解时间复杂度降低到O(n)。

单调队列原理

单调队列是一种特殊的队列,它保证了队列中的元素按照一定的顺序排列。在求解滑动窗口最大值问题时,我们使用一个单调递减的队列来维护窗口内的最大值。

单调队列的基本操作如下:

1. 入队:当新元素要进入队列时,如果队列不为空且新元素大于队列尾部的元素,则将队列尾部的元素出队,直到新元素小于或等于队列尾部的元素。这样可以保证队列尾部始终是窗口内的最大值。

2. 出队:当窗口滑动时,如果出队元素是队列头部的元素,则将其出队。如果出队元素不是队列头部的元素,则说明它不是窗口内的最大值,因此不需要出队。

代码实现

以下是一个使用单调队列求解滑动窗口最大值问题的Python代码示例:

python

from collections import deque

def maxSlidingWindow(nums, k):


if not nums or k <= 0:


return []



单调递减队列


queue = deque()


result = []



for i in range(len(nums)):


移除窗口外的元素


if queue and queue[0] < i - k + 1:


queue.popleft()



移除小于当前元素的元素


while queue and nums[queue[-1]] < nums[i]:


queue.pop()



添加当前元素


queue.append(i)



当窗口大小达到k时,添加当前窗口的最大值


if i >= k - 1:


result.append(nums[queue[0]])



return result

测试代码


nums = [1,3,-1,-3,5,3,6,7]


k = 3


print(maxSlidingWindow(nums, k)) 输出: [3,3,5,5,6,7]


性能分析

使用单调队列求解滑动窗口最大值问题的算法时间复杂度为O(n),空间复杂度为O(k)。这是因为队列中最多存储k个元素,且每个元素只入队和出队一次。

总结

本文介绍了如何使用单调队列优化滑动窗口最大值问题的求解过程。单调队列通过维护一个单调递减的队列,实现了在O(1)时间内完成元素的入队和出队操作,从而将整个问题的求解时间复杂度降低到O(n)。在实际应用中,这种方法可以有效地解决滑动窗口最大值问题,提高算法的效率。