数据结构与算法之 leetcode 队列优化 双端队列 / 优先队列

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


队列优化:双端队列与优先队列在LeetCode中的应用

在数据结构与算法的学习过程中,队列是一种非常基础且常用的数据结构。它遵循“先进先出”(FIFO)的原则,即最先进入队列的元素最先被取出。在某些特定的场景下,标准的队列可能无法满足我们的需求。为了应对这些挑战,我们可以使用双端队列和优先队列这两种优化后的队列结构。本文将围绕这两种队列在LeetCode平台上的应用进行探讨。

双端队列

定义

双端队列(Deque,Double-ended queue)是一种支持在两端进行插入和删除操作的数据结构。它既可以像队列一样从一端插入元素,从另一端删除元素,也可以像栈一样从两端进行操作。

实现方式

在Python中,可以使用列表来实现双端队列。以下是使用列表实现双端队列的基本操作:

python

class Deque:


def __init__(self):


self.items = []

def is_empty(self):


return len(self.items) == 0

def add_front(self, item):


self.items.insert(0, item)

def add_rear(self, item):


self.items.append(item)

def remove_front(self):


if not self.is_empty():


return self.items.pop(0)


return None

def remove_rear(self):


if not self.is_empty():


return self.items.pop()


return None

def size(self):


return len(self.items)


LeetCode应用

在LeetCode中,双端队列常用于解决一些需要从两端进行操作的问题。以下是一些使用双端队列解决LeetCode问题的例子:

1. 题目:232. 用栈实现队列(Implement Queue using Stacks)

- 题目描述:使用两个栈实现一个队列,支持队列的基本操作(入队、出队、队首元素)。

- 解题思路:使用一个栈来存储入队元素,另一个栈来存储出队元素。当出队栈为空时,将入队栈的所有元素逆序转移到出队栈中。

- 代码实现:

python

class MyQueue:

def __init__(self):


self.in_stack = []


self.out_stack = []

def push(self, x: int) -> None:


self.in_stack.append(x)

def pop(self) -> int:


if not self.out_stack:


while self.in_stack:


self.out_stack.append(self.in_stack.pop())


return self.out_stack.pop()

def peek(self) -> int:


if not self.out_stack:


while self.in_stack:


self.out_stack.append(self.in_stack.pop())


return self.out_stack[-1]

def empty(self) -> bool:


return not self.in_stack and not self.out_stack


2. 题目:641. 设计循环双端队列(Design Circular Deque)

- 题目描述:设计一个循环双端队列,支持在队列的两端进行插入和删除操作。

- 解题思路:使用一个固定大小的数组来实现循环双端队列,通过维护两个指针来表示队列的头部和尾部。

- 代码实现:

python

class MyCircularDeque:

def __init__(self, k: int):


self.capacity = k


self.queue = [0] k


self.head = 0


self.tail = 0


self.size = 0

def insertFront(self, value: int) -> bool:


if self.size == self.capacity:


return False


self.head = (self.head - 1 + self.capacity) % self.capacity


self.queue[self.head] = value


self.size += 1


return True

def insertLast(self, value: int) -> bool:


if self.size == self.capacity:


return False


self.queue[self.tail] = value


self.tail = (self.tail + 1) % self.capacity


self.size += 1


return True

def deleteFront(self) -> bool:


if self.size == 0:


return False


self.head = (self.head + 1) % self.capacity


self.size -= 1


return True

def deleteLast(self) -> bool:


if self.size == 0:


return False


self.tail = (self.tail - 1 + self.capacity) % self.capacity


self.size -= 1


return True

def getFront(self) -> int:


if self.size == 0:


return -1


return self.queue[self.head]

def getRear(self) -> int:


if self.size == 0:


return -1


return self.queue[(self.tail - 1 + self.capacity) % self.capacity]

def isEmpty(self) -> bool:


return self.size == 0

def isFull(self) -> bool:


return self.size == self.capacity


优先队列

定义

优先队列(Priority Queue)是一种特殊的队列,它根据元素的优先级对元素进行排序。在优先队列中,具有最高优先级的元素最先被取出。

实现方式

在Python中,可以使用内置的`heapq`模块来实现优先队列。`heapq`模块提供了一个最小堆的实现,可以通过调整元素顺序来实现优先队列的功能。

以下是使用`heapq`模块实现优先队列的基本操作:

python

import heapq

class PriorityQueue:


def __init__(self):


self.heap = []

def is_empty(self):


return len(self.heap) == 0

def push(self, item, priority):


heapq.heappush(self.heap, (-priority, item))

def pop(self):


if not self.is_empty():


return heapq.heappop(self.heap)[1]


return None

def size(self):


return len(self.heap)


LeetCode应用

在LeetCode中,优先队列常用于解决需要根据元素优先级进行操作的问题。以下是一些使用优先队列解决LeetCode问题的例子:

1. 题目:347. 前 K 个高频元素(Top K Frequent Elements)

- 题目描述:给定一个非空整数数组,返回其中出现频率最高的k个元素。

- 解题思路:使用哈希表统计每个元素的频率,然后使用优先队列存储频率最高的k个元素。

- 代码实现:

python

import collections


import heapq

class Solution:


def topKFrequent(self, nums: List[int], k: int) -> List[int]:


counter = collections.Counter(nums)


heap = []


for num, freq in counter.items():


heapq.heappush(heap, (freq, num))


if len(heap) > k:


heapq.heappop(heap)


return [num for _, num in sorted(heap, reverse=True)]


2. 题目:23. 合并K个排序链表(Merge k Sorted Lists)

- 题目描述:合并k个已排序的链表。

- 解题思路:使用优先队列存储每个链表的头部元素,并按照元素值进行排序。每次从优先队列中取出最小元素,将其添加到结果链表中,并更新优先队列。

- 代码实现:

python

import heapq

class ListNode:


def __init__(self, val=0, next=None):


self.val = val


self.next = next

class Solution:


def mergeKLists(self, lists: List[ListNode]) -> ListNode:


dummy = ListNode()


current = dummy


heap = []


for node in lists:


if node:


heapq.heappush(heap, (node.val, node))


while heap:


_, node = heapq.heappop(heap)


current.next = node


current = current.next


if node.next:


heapq.heappush(heap, (node.next.val, node.next))


return dummy.next


总结

本文介绍了双端队列和优先队列这两种优化后的队列结构,并探讨了它们在LeetCode平台上的应用。通过学习这些数据结构,我们可以更好地解决一些具有挑战性的问题。在实际应用中,选择合适的数据结构对于提高算法效率至关重要。希望本文能对您有所帮助。