1. 单调队列与单调栈基础概念
单调队列和单调栈是两种特殊的线性数据结构,它们通过维护元素的单调性来高效解决特定问题。单调队列主要用于维护滑动窗口内的极值,而单调栈则用于快速找到元素的前驱/后继极值关系。
单调队列的核心特征是队列中的元素保持严格的单调递增或递减顺序。以维护最小值为例,当新元素入队时,会从队尾移除所有大于等于它的元素,确保队列始终单调递增。这样,队首元素就是当前窗口的最小值。
单调栈则通过保持栈内元素的单调性,可以快速找到第一个比当前元素大或小的前驱/后继。例如,维护一个单调递增栈,当遇到比栈顶小的元素时,弹出栈顶直到满足单调性,此时栈顶就是当前元素的左侧第一个较小值。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 单调队列的实现与优化
2.1 基本实现模板
以滑动窗口最小值为例,C++实现如下:
cpp复制vector<int> minSlidingWindow(vector<int>& nums, int k) {
deque<int> q;
vector<int> res;
for(int i=0; i<nums.size(); ++i){
// 移除超出窗口范围的元素
while(!q.empty() && q.front() <= i-k) q.pop_front();
// 维护单调递增性
while(!q.empty() && nums[q.back()] >= nums[i]) q.pop_back();
q.push_back(i);
// 窗口形成后记录结果
if(i >= k-1) res.push_back(nums[q.front()]);
}
return res;
}
2.2 多重背包优化应用
单调队列可以优化多重背包问题的动态规划解法。传统多重背包的时间复杂度为O(NVK),使用单调队列可降为O(N*V):
cpp复制for(int i=1; i<=n; ++i){
for(int j=0; j<w[i]; ++j){
deque<int> q;
for(int k=0; k*w[i]+j <= V;
