数据结构与算法之数据结构 队列经典问题 滑动窗口最大值 / 广度优先

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


摘要:

队列是一种先进先出(FIFO)的数据结构,它在许多算法中扮演着重要的角色。本文将围绕队列这一数据结构,探讨两个经典问题:滑动窗口最大值和广度优先搜索。通过分析这两个问题,我们将深入了解队列在解决实际问题中的应用。

一、

队列是一种常用的数据结构,它支持两种基本的操作:入队(enqueue)和出队(dequeue)。在队列中,元素按照它们被插入的顺序进行排列,先进入队列的元素将先被移除。队列在许多算法中都有应用,如广度优先搜索、滑动窗口最大值等。

二、滑动窗口最大值

滑动窗口最大值问题是一个在队列中非常常见的问题。给定一个数组和一个窗口大小,我们需要找出每个窗口中的最大值。以下是一个使用队列解决滑动窗口最大值问题的示例代码:

python

from collections import deque

def max_sliding_window(nums, k):


if not nums or k <= 0:


return []

result = []


queue = deque()

for i in range(len(nums)):


移除窗口外的元素


if queue and queue[0] == i - k:


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(max_sliding_window(nums, k))


在上面的代码中,我们使用了一个双端队列(deque)来存储窗口内的元素。队列的头部始终是当前窗口的最大值。当窗口滑动时,我们移除队列头部的元素(如果它已经不在窗口内),并且移除队列尾部小于当前元素的元素。这样,队列的头部始终是当前窗口的最大值。

三、广度优先搜索

广度优先搜索(BFS)是一种使用队列实现的图遍历算法。在BFS中,我们按照层次遍历图中的节点。以下是一个使用队列实现BFS的示例代码:

python

from collections import deque

def bfs(graph, start):


visited = set()


queue = deque([start])

while queue:


node = queue.popleft()


if node not in visited:


visited.add(node)


for neighbor in graph[node]:


if neighbor not in visited:


queue.append(neighbor)

return visited

示例


graph = {


'A': ['B', 'C'],


'B': ['D', 'E'],


'C': ['F'],


'D': [],


'E': ['F'],


'F': []


}


start_node = 'A'


print(bfs(graph, start_node))


在上面的代码中,我们使用了一个集合(set)来存储已经访问过的节点,以避免重复访问。我们使用一个队列来存储待访问的节点。在每次迭代中,我们从队列中取出一个节点,并将其邻居节点加入队列。这样,我们就可以按照层次遍历图中的节点。

四、总结

本文通过分析滑动窗口最大值和广度优先搜索这两个问题,展示了队列在解决实际问题中的应用。滑动窗口最大值问题通过维护一个双端队列来找到每个窗口的最大值,而广度优先搜索则通过队列实现图的层次遍历。这两个问题都是队列在实际应用中的经典案例,有助于我们更好地理解队列的特性和使用方法。

通过学习和掌握这些经典问题,我们可以提高自己在数据结构与算法方面的能力,为解决更复杂的问题打下坚实的基础。