滑动窗口
入坑题目
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 const int N = 1e5 + 5; 5 const int inf = 0x3f3f3f3f; 6 int n, m; 7 int q1[N], q2[N], h1 = 1, h2 = 1, t1, t2; 8 9 struct A{ 10 int x, y; 11 }a[N]; 12 bool cmp(A x, A y){ 13 return x.x < y.x; 14 } 15 16 int main(){ 17 int ans = inf; 18 scanf("%d%d", &n, &m); 19 for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].x, &a[i].y); 20 sort(a + 1, a + n + 1, cmp); 21 for(int i = 1, j = 0; i <= n; i++){ 22 while(h1 <= t1 && q1[h1] < i) h1++; 23 while(h2 <= t2 && q2[h2] < i) h2++; 24 while(a[q1[h1]].y - a[q2[h2]].y < m && j < n){ 25 j++; 26 while(h1 <= t1 && a[q1[t1]].y <= a[j].y) t1--; 27 q1[++t1] = j; 28 while(h2 <= t2 && a[q2[t2]].y >= a[j].y) t2--; 29 q2[++t2] = j; 30 } 31 if(a[q1[h1]].y - a[q2[h2]].y >= m) ans = min(ans, a[j].x - a[i].x); 32 } 33 printf("%d", ans == inf ? -1 : ans); 34 return 0; 35 }
先看滑动窗口
打个比方
即您现在有一只宽度固定的窗框
窗外有连绵起伏的山
假设您只能看到窗框中的景色
窗框可以平行于山脉水平滑动
对于窗框的每个位置
求问能看到的最高的山
现在有个数列表示山的高度
3 6 3 2 4 5 2 4 5
窗框宽度为3
则不同位置能看到的情况从左到右依次有
{3, 6, 3}, {6, 3, 2}, {3, 2, 4}, {2, 4, 5}, {4, 5, 2}, {5, 2, 4}, {2, 4, 5}
暴力求解复杂度O(n*m)(n为山脉长度 m为窗框宽度)
使用单调队列可优化至 O(n)
统计一个最大单调队列(存储下标)
把当前区间记作[l, r]
当转换为[l + 1, r + 1]时 删除队列中小于等于l的 插入r
一般的变式:
1。窗框条件改变
如入坑题就是窗框条件变为最大数减最小数差值大于d
2。维护答案改变
3。单调内容改变
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理