滑动窗口c++
时间: 2025-04-23 17:13:55 浏览: 28
### C++ 中滑动窗口算法的实现与解释
#### 概念介绍
滑动窗口是一种常用的优化技巧,特别适用于处理数组或字符串的一系列连续子序列问题。通过维护一个动态调整大小的窗口,在遍历过程中不断更新窗口内的状态,从而高效解决问题。
#### 时间复杂度特性
由于滑动窗口机制不会重复访问已经考察过的元素,因此整体的时间复杂度通常是线性的 O(n),而非嵌套循环带来的平方级别开销[^1]。
#### 应用场景举例
- **统计得分小于 K 的子数组数目**:利用前缀和配合二分查找快速定位满足条件的边界。
- **长度最小的子数组**:寻找第一个使得累积和达到目标值的位置,并在此基础上尝试收缩左侧边界以找到更短的有效区间。
- **最小覆盖子串**:采用双指针策略扩展右侧直至包含所有必需字符,随后逐步缩减左侧直到刚好失去合法性为止。
- **可见点的最大数目**:借助 map 或字典树结构记录角度范围内的障碍物分布情况。
- **最长合法子字符串的长度**:运用栈或者双向队列追踪当前有效括号配对关系及其极限位置。
#### 经典型题目解析
对于给定的任务——在一个固定宽度 `k` 下计算每轮移动后的局部极大/极小值:
```cpp
class MaxMinSlidingWindow {
public:
vector<int> maxSlidingWindow(const vector<int>& nums, int k) {
deque<int> dq;
vector<int> result;
for (int i = 0; i < nums.size(); ++i) {
// 移除不在窗口范围内的索引
if (!dq.empty() && dq.front() == i - k) dq.pop_front();
// 移除所有比新加入元素小的项
while (!dq.empty() && nums[dq.back()] < nums[i])
dq.pop_back();
dq.push_back(i);
// 当窗口形成后开始收集结果
if (i >= k - 1)
result.push_back(nums[dq.front()]);
}
return result;
}
};
```
上述代码展示了如何使用双端队列(deque)来跟踪潜在的最大值候选者,确保每次迭代都能即时获取到最新的最大值而无需额外扫描整个窗口内部的内容[^3]。
#### 变种案例探讨
针对特定约束条件下(如允许翻转一定数量零值),可以通过引入计数器变量辅助判断何时应当扩张或收缩窗口边界,如下所示的例子即是在限定次数内最大化连续 '1' 的片段长度:
```cpp
class Solution {
public:
int longestOnes(vector<int>& A, int K) {
int left = 0, right = 0, zeros = 0, maxLength = 0;
while (right < A.size()) {
if (A[right++] == 0) ++zeros;
// 超过可容忍限度则同步前进左右两端
while (zeros > K)
if (A[left++] == 0) --zeros;
maxLength = max(maxLength, right - left);
}
return maxLength;
}
};
```
这段程序巧妙地结合了贪心思想与滑动窗口框架,实现了高效的解决方案设计[^2]。
阅读全文
相关推荐















