隊列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)

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; }

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

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 """

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; } };