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

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


队列滑动窗口最大值算法(单调队列)详解

在数据结构与算法领域,滑动窗口是一种常见的处理序列数据的方法。它通过维护一个固定大小的窗口,在序列中滑动,从而对窗口内的数据进行处理。在许多实际问题中,我们经常需要找到滑动窗口中的最大值。本文将围绕这一主题,详细介绍使用单调队列解决队列滑动窗口最大值算法的方法。

单调队列简介

单调队列是一种特殊的队列,它保证了队列中的元素按照一定的顺序排列。在单调队列中,有两种常见的类型:单调递增队列和单调递减队列。单调递增队列中的元素从队首到队尾依次递增,而单调递减队列中的元素则相反。

单调队列在解决某些问题时具有很高的效率,因为它可以快速地找到队列中的最大值或最小值。我们将使用单调递减队列来解决滑动窗口最大值问题。

滑动窗口最大值问题

假设有一个整数数组 `nums`,我们需要找到所有滑动窗口的最大值。滑动窗口的大小为 `k`,窗口从数组的第一个元素开始,每次向右滑动一个元素。

例如,对于数组 `nums = [1, 3, -1, -3, 5, 3, 6, 7]` 和窗口大小 `k = 3`,我们需要找到以下滑动窗口的最大值:


[1, 3, -1] -> 3


[3, -1, -3] -> 3


[-1, -3, 5] -> 5


[-3, 5, 3] -> 5


[5, 3, 6] -> 6


[3, 6, 7] -> 7


单调队列解决滑动窗口最大值问题

为了使用单调队列解决滑动窗口最大值问题,我们需要维护一个单调递减队列。队列的元素将按照从大到小的顺序排列,队列的头部将始终是当前窗口的最大值。

以下是使用单调队列解决滑动窗口最大值问题的步骤:

1. 初始化一个空的单调递减队列。

2. 遍历数组 `nums`,对于每个元素:

- 将当前元素从队列的尾部开始,与队列中的元素进行比较。

- 如果当前元素大于队列中的元素,则将队列中的元素出队,直到当前元素不再大于队列中的元素。

- 将当前元素入队。

- 如果队列的长度小于窗口大小 `k`,则继续遍历下一个元素。

- 如果队列的长度等于窗口大小 `k`,则将队列的头部元素(即当前窗口的最大值)添加到结果列表中。

3. 返回结果列表。

代码实现

以下是使用Python实现的滑动窗口最大值算法:

python

def maxSlidingWindow(nums, k):


from collections import deque


queue = deque()


result = []



for i, num in enumerate(nums):


移除窗口外的元素


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


queue.popleft()



移除小于当前元素的元素


while queue and queue[-1] < num:


queue.pop()



将当前元素加入队列


queue.append(num)



当窗口大小等于k时,将队列头部元素加入结果列表


if i >= k - 1:


result.append(queue[0])



return result

测试代码


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


k = 3


print(maxSlidingWindow(nums, k))


总结

本文详细介绍了使用单调队列解决滑动窗口最大值问题的方法。通过维护一个单调递减队列,我们可以快速地找到滑动窗口中的最大值。这种方法在处理大数据量时具有很高的效率,是解决滑动窗口问题的常用技巧。

在实际应用中,我们可以根据具体问题调整单调队列的实现方式,以达到最优的性能。希望本文能够帮助读者更好地理解和应用单调队列这一数据结构。