数据结构与算法之数据结构 队列面试高频 优先队列 / 滑动窗口

数据结构与算法阿木 发布于 2025-07-11 6 次阅读


摘要:在数据结构与算法的面试中,队列是一个经常被考察的数据结构。本文将围绕优先队列和滑动窗口这两个面试高频主题,详细解析其原理、实现和应用,帮助读者更好地理解和应对面试中的相关问题。

一、

队列是一种先进先出(FIFO)的数据结构,广泛应用于各种场景。在面试中,优先队列和滑动窗口是两个高频考点。本文将分别介绍这两个主题,并给出相应的代码实现。

二、优先队列

1. 原理

优先队列是一种特殊的队列,它允许元素按照优先级进行排序。在优先队列中,元素按照优先级从高到低排列,优先级高的元素先被处理。

2. 实现方式

优先队列可以使用多种方式实现,其中最常用的是二叉堆。二叉堆是一种完全二叉树,满足以下性质:

(1)最大堆:父节点的值大于或等于其子节点的值。

(2)最小堆:父节点的值小于或等于其子节点的值。

下面是使用最大堆实现优先队列的代码示例:

python

class PriorityQueue:


def __init__(self):


self.heap = []

def is_empty(self):


return len(self.heap) == 0

def push(self, item):


self.heap.append(item)


self._sift_up(len(self.heap) - 1)

def pop(self):


if self.is_empty():


return None


root = self.heap[0]


self.heap[0] = self.heap.pop()


self._sift_down(0)


return root

def _sift_up(self, index):


while index > 0:


parent_index = (index - 1) // 2


if self.heap[parent_index] < self.heap[index]:


self.heap[parent_index], self.heap[index] = self.heap[index], self.heap[parent_index]


index = parent_index


else:


break

def _sift_down(self, index):


while index < len(self.heap):


left_child_index = 2 index + 1


right_child_index = 2 index + 2


largest_index = index


if left_child_index < len(self.heap) and self.heap[left_child_index] > self.heap[largest_index]:


largest_index = left_child_index


if right_child_index < len(self.heap) and self.heap[right_child_index] > self.heap[largest_index]:


largest_index = right_child_index


if largest_index != index:


self.heap[index], self.heap[largest_index] = self.heap[largest_index], self.heap[index]


index = largest_index


else:


break


3. 应用

优先队列广泛应用于各种场景,如任务调度、资源分配、图算法等。以下是一个使用优先队列进行任务调度的示例:

python

def task_scheduler(tasks, n):


pq = PriorityQueue()


for i in range(n):


pq.push((tasks[i], i))


result = []


while not pq.is_empty():


_, index = pq.pop()


result.append(index)


return result

示例


tasks = [1, 2, 3, 4, 5]


n = 5


result = task_scheduler(tasks, n)


print(result) 输出:[0, 1, 2, 3, 4]


三、滑动窗口

1. 原理

滑动窗口是一种处理序列数据的方法,它通过在序列上滑动一个固定大小的窗口来获取子序列。在滑动窗口中,窗口的大小、移动步长和窗口内的元素可以自定义。

2. 实现方式

滑动窗口可以使用多种方式实现,以下是一个使用双端队列实现滑动窗口的代码示例:

python

from collections import deque

def sliding_window(nums, k):


result = []


window = deque()


for i, num in enumerate(nums):


while window and window[-1] < num:


window.pop()


window.append(num)


if i >= k - 1:


result.append(window[0])


if window[0] == nums[i - k + 1]:


window.popleft()


return result

示例


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


k = 3


result = sliding_window(nums, k)


print(result) 输出:[3, 3, 5, 5, 6, 7]


3. 应用

滑动窗口广泛应用于字符串匹配、滑动平均、滑动最大值等问题。以下是一个使用滑动窗口进行字符串匹配的示例:

python

def string_matching(s, p):


result = []


for i in range(len(s) - len(p) + 1):


if s[i:i + len(p)] == p:


result.append(i)


return result

示例


s = "ababcabcab"


p = "abc"


result = string_matching(s, p)


print(result) 输出:[2, 5]


四、总结

本文详细介绍了优先队列和滑动窗口这两个面试高频主题。通过分析其原理、实现和应用,读者可以更好地理解和应对面试中的相关问题。在实际应用中,优先队列和滑动窗口具有广泛的应用场景,掌握它们对于提高编程能力具有重要意义。