队列queue
c++
- 定义
queue<int> queue;
- 入队
queue.push(num);
- 出队
queue.pop();
//队列为空时出队报错 if(!queue.empty()) queue.pop();
- 获取队列大小、队首、队尾元素方法
queue.size()
queue.front()
queue.back()
- 清空队列
while(!queue.empty()){ queue.pop(); }
python
python中的队列直接用List实现 内核即:
queue = []
但更常用双端队列,见下面内容。
双端队列deque
双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。
c++
- 定义
deque<int> deque;
- 入队
// 从队首入队 deque.push_front(num); // 从队尾入队 deque.push_back(num); /*没有了que.push()方法*/
- 出队
// 从队首出队 deque.pop_front(num); // 从队尾出队 deque.pop_back(num); /*没有了que.pop()方法*/
- 获取队列大小、队首、队尾元素方法
deeue.size()
deeue.front()
deeue.back()
- 清空队列
while(!deque.empty()){ deque.pop_back(); //deque.pop_front(); }
python
python中的双端队列在内置模块collections中,是python标准库;collections包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择。
这里只说deque,其他的还有例如
- 计数器(Counter)
- 默认字典(defaultdict)
- 有序字典(OrderedDict)
- 可命名元组(namedtuple)
- 定义
deque = collections.deque()
- 入队
# 从队尾入队 deque.append(num) # 从队尾入队 deque.appendleft(num)
- 出队
# 从队尾出队 deque.pop() # 从队尾出队 deque.popleft()
- 获取队列大小、队首、队尾元素方法
len(deque) # 同时还可以对队列中某个元素出现个数进行统计 deque.count(num) # 返回对首元素 deque[0] # 返回队尾元素 deque[-1]
- 清空队列
deque.clear()
example_1:序列上滑动窗口中的最大值
题目来源:剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
vector<int> maxSlidingWindow(vector<int>& nums, int k) { //滑动窗口 + 维护一个单调的队列 deque<int> monoQueue; //c++中也有deque 常用这个才对 vector<int> res; int n = nums.size(); for(int i = -k+1;i<n-k+1;i++){ int j = i+k-1; // 如果出窗口的刚好是上一轮的最大值 if(i>0 && nums[i-1] == monoQueue.front()){ monoQueue.pop_front(); } //保证单调的队列 while(!monoQueue.empty() && monoQueue.back() <nums[j]){ monoQueue.pop_back(); } monoQueue.push_back(nums[j]); if(i>=0){ res.push_back(monoQueue.front()); } } return res; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: # 使用双端队列(单调队列) res= [] monoQueue = collections.deque() n = len(nums) for i,j in zip(range(-k+1,n-k+1),range(n)): # 滑动窗口还可以这样???? 学习了 if i > 0 and monoQueue[0] == nums[i-1]: # 如果最大值刚好是刚被弹出的那个元素,那么要把队列首pop出去 monoQueue.popleft() # 保证monoQueue递减 while monoQueue and monoQueue[-1] < nums[j]: monoQueue.pop() monoQueue.append(nums[j]) if i>=0: res.append(monoQueue[0]) return res
example_2:自定义MaxQueue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class MaxQueue: """ 菜鸡做法 维护一个单调队列 # 首先如果只维护一个最大值,但是当最大值出队后,不能用O(1)的时间来找下一个max value # 利用 数据结构 来实现,即经常使用的 “空间换时间” 。 def __init__(self): self.queue = [] self.monoque = collections.deque() def max_value(self) -> int: if self.monoque: return self.monoque[0] else: return -1 def push_back(self, value: int) -> None: self.queue.append(value) while self.monoque and self.monoque[-1]<value: self.monoque.pop() self.monoque.append(value) def pop_front(self) -> int: if self.queue: if self.queue[0]==self.monoque[0]: self.monoque.popleft() ret = self.queue[0] self.queue = self.queue[1:] return ret else: return -1 """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class MaxQueue { queue<int> que; deque<int> deq; public: MaxQueue() { } int max_value() { return deq.empty() ? -1 : deq.front(); } void push_back(int value) { que.push(value); while(!deq.empty() && deq.back() < value) deq.pop_back(); deq.push_back(value); } int pop_front() { if(que.empty()) return -1; int val = que.front(); if(val == deq.front()) deq.pop_front(); que.pop(); return val; } };