ac 154. 滑动窗口
如果用普通窗口 每一次往右边移动一格(时间n)进行一次判断(时间k)需要 nk 的时间复杂度
用排序好的窗口, 比如一开始输入
8 3
1 3 -1 -3 5 3 6 7
先是 1 这个数字再窗口内, 然后 由于第二个数字 3比1要小所以不记录队列中
再是 -1 这个数字 比1小所以记录 此时队列为 [1 ,-1](当然是用数组的下标来标记实际上是 [0, 1]
再下一个数字同理 1, -1, -3
再下一个数字 此时 由于大于 了窗口长度 所以先把 1 去除 变成 [-1, -3](实际[1, 2])
再比较 5 这个数字 由于比-3要大所以不记录,如此一直比较。
当i的大小大于窗口长度就可以开始输出了
输出最大值同理
// 常见模型:找出滑动窗口中的最大值/最小值
// int hh = 0, tt = -1;
// for (int i = 0; i < n; i ++ )
// {
// while (hh <= tt && check_out(q[hh])) hh ++ ; // 判断队头是否滑出窗口
// while (hh <= tt && check(q[tt], i)) tt -- ;
// q[ ++ tt] = i;
// }
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int q[N], a[N];
int main() {
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i ++) {
cin >> a[i];
}
int hh = 0, tt = -1;
// i 本质是窗口的依次经历的右端点
for (int i = 0; i < n; i ++ )
{
// 当前窗口区间是[i - k + 1, i]
if (hh <= tt && q[hh] < i - k + 1) hh ++; //队首小于当前窗口最左边就舍去
while (hh <= tt && a[q[tt]] >= a[i]) tt -- ; //队尾(左为首,右为尾)大于当前的元素,那么他一定不会被当成最小值输出,就删掉
q[ ++ tt] = i;//再加当前的数字
if(i >= k - 1) printf("%d ", a[q[hh]]);
}
puts("");
hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
if (hh <= tt && q[hh] < i - k + 1) hh ++;
while (hh <= tt && a[q[tt]] <= a[i]) tt -- ;
q[ ++ tt] = i;
if(i >= k - 1) printf("%d ", a[q[hh]]);
}
puts("");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人