使用双端队列维护单调递增索引序列可高效实现滑动窗口最小值,遍历数组时维护队列单调性并移除超范围元素,每步将队首最小值加入结果,时间复杂度O(n)。

在C++中实现滑动窗口最小值,常用的方法是使用双端队列(deque)来维护窗口内元素的索引,保证队首始终是当前窗口的最小值。这种方法时间复杂度为O(n),每个元素最多入队出队一次。
使用双端队列维护单调递增序列
核心思想是维护一个单调递增的双端队列,存储的是数组下标而非元素值,这样能判断元素是否还在窗口范围内。
具体操作如下:
- 遍历数组时,如果队列非空且队尾对应元素大于等于当前元素,则从队尾弹出,保持队列单调性
- 将当前元素下标加入队尾
- 检查队首元素是否已滑出窗口(下标小于 i - k + 1),若超出则从队首弹出
- 当遍历到第k个元素后,每步将队首对应值加入结果
示例代码:
立即学习“C++免费学习笔记(深入)”;
#include
#include
using namespace std;
vector
deque
vector
for (int i = 0; i
// 移除队尾比当前元素大的索引,保持递增
while (!dq.empty() && nums[dq.back()] >= nums[i])
dq.pop_back();
// 加入当前索引
dq.push_back(i);
// 移除超出窗口范围的队首元素
if (dq.front()
dq.pop_front();
// 窗口形成后记录最小值
if (i >= k - 1)
result.push_back(nums[dq.front()]);
}
return result;
}
处理边界情况
需要注意输入合法性判断,比如窗口大小k大于数组长度或k为0的情况。
可以在函数开头添加检查:
if (nums.empty() || k nums.size())
return {};
实际应用场景
该方法适用于需要频繁查询滑动区间最值的问题,如数据流中的局部最小值、图像处理中的滤波窗口等。双端队列法比暴力解法(每次遍历窗口找最小)效率更高,适合大规模数据处理。
基本上就这些,关键在于理解队列中维护的是可能成为最小值的候选索引,而不是所有元素。











