C++ STL deque(双端队列)->单调队列 使用方法

首先声明 : 本人纯小白 如有错误 敬请各位大佬指正

std::deque 是 C++ STL 库 提供的一种 双端队列 其常用成员函数有:
empty() : 判断队列是否为空
size() : 队列元素个数
push_back(值): 队尾插入元素
push_front(值): 队首插入元素
pop_front():弹出对头元素
pop_back():弹出队尾元素
back():返回队尾元素的值(引用返回)
front() :返回对首元素的值(引用返回)

常见应用:

有了上面的一些常用操作,做题也就够用了 ,deque的一种经典应用就是滑动窗口(slide window)

直接上题目:
原题链接:滑动窗口
题目大意: 给你n 个元素和一个 长度为 k 的窗口 窗口从第一个元素开始向后移动 要求输出每次窗口中的最小值最大值

例如,对于序列 [ 1 , 3 , − 1 , − 3 , 5 , 3 , 6 , 7 ] [1,3,-1,-3,5,3,6,7] [1,3,1,3,5,3,6,7] 以及 k = 3 k = 3 k=3,有如下过程:

窗口位置 最小值 最大值 [1   3  -1] -3   5   3   6   7  − 1 3  1  [3  -1  -3]  5   3   6   7  − 3 3  1   3 [-1  -3   5]  3   6   7  − 3 5  1   3  -1 [-3   5   3]  6   7  − 3 5  1   3  -1  -3  [5   3   6]  7  3 6  1   3  -1  -3   5  [3   6   7] 3 7 \def\arraystretch{1.2} \begin{array}{|c|c|c|}\hline \textsf{窗口位置} & \textsf{最小值} & \textsf{最大值} \\ \hline \verb![1 3 -1] -3 5 3 6 7 ! & -1 & 3 \\ \hline \verb! 1 [3 -1 -3] 5 3 6 7 ! & -3 & 3 \\ \hline \verb! 1 3 [-1 -3 5] 3 6 7 ! & -3 & 5 \\ \hline \verb! 1 3 -1 [-3 5 3] 6 7 ! & -3 & 5 \\ \hline \verb! 1 3 -1 -3 [5 3 6] 7 ! & 3 & 6 \\ \hline \verb! 1 3 -1 -3 5 [3 6 7]! & 3 & 7 \\ \hline \end{array}

### 双端队列在PTA中的实现与应用 #### 什么是双端队列双端队列Deque, Double-ended Queue)是一种允许从两端进行插入和删除操作的数据结构。这种特性使得它非常适合用于需要灵活处理数据的情况,比如模拟某些特定场景下的入队和出队行为。 在C++标准模板库(STL)中,`std::deque` 是一种常见的双端队列实现[^1]。它的特点是支持快速随机访问以及高效的头部和尾部插入/删除操作。尽管 `std::deque` 的底层实现较为复杂,但它提供了类似于动态数组的功能,同时保留了链表的部分优势。 --- #### PTA 中双端队列的应用实例 在编程题解平台(如PTA),双端队列通常应用于以下几种典型问题: 1. **滑动窗口最大值** 这类问题是双端队列的经典应用场景之一。给定一个长度为 \(n\) 的数组和大小为 \(k\) 的滑动窗口,要求返回每个窗口的最大值。利用双端队列可以从两侧高效地维护当前窗口内的候选最大值。 下面是一个基于 C++ STL 的解决方案: ```cpp #include <iostream> #include <deque> using namespace std; void slidingWindowMax(int arr[], int n, int k) { deque<int> dq; // 存储索引 for (int i = 0; i < n; ++i) { while (!dq.empty() && arr[dq.back()] <= arr[i]) { dq.pop_back(); // 移除无用的小值 } dq.push_back(i); // 添加新元素 if (dq.front() <= i - k) { // 超过窗口范围的移除 dq.pop_front(); } if (i >= k - 1) { // 输出结果 cout << arr[dq.front()] << " "; } } } ``` 2. **单调队列优化 DP 或 BFS** 在一些动态规划或广度优先搜索算法中,可以通过双端队列加速状态转移过程。例如,在解决最短路径问题时,如果边权均为正数,则可以使用双端队列代替普通的队列来减少不必要的松弛操作。 3. **回文串检测** 利用双端队列可以从两头读取字符的特点,它可以用来判断字符串是否为回文形式。这种方法的时间复杂度接近 O(n),效率较高。 4. **多方向扩展的 BFS 题目** 当题目涉及多个起点或者终点的情况下,双端队列能够很好地满足需求。例如,“最近公共祖先”、“最小步数到达目标节点”等问题都可以借助该工具完成求解。 --- #### 使用注意事项 虽然双端队列功能强大,但在实际编码过程中需要注意以下几个方面: - 插入和删除操作仅限于首尾位置;中间位置的操作会引发异常。 - 如果频繁调用 push/pop 方法可能会导致性能下降,因此应尽量避免嵌套循环内多次执行这些指令。 - 对于大容量的需求考虑预分配空间以提高运行速度。 --- ### 总结 综上所述,双端队列作为一种重要的基础数据结构,在许多领域都有着广泛的应用价值。特别是在像 PTA 平台这样的竞赛环境中更是如此——合理运用这一利器往往能帮助选手更加快捷准确地解决问题[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值