滑动窗口:双指针背后的不变量
窗口题看起来多,骨架却相似:维护合法区间,并在扩张与收缩间切换。
滑动窗口是双指针在序列上的特化。关键不是背模板,而是写清:窗口内统计量代表什么,以及何时右扩、何时左缩。
通用骨架
func sliding(s string) int {
left := 0
best := 0
// window 统计结构
for right := 0; right < len(s); right++ {
// 1. 纳入 s[right]
for /* 窗口不合法 */ {
// 2. 剔除 s[left]; left++
}
// 3. 用合法窗口更新答案
best = max(best, right-left+1)
}
return best
}
两类典型
- 最长合法:尽量扩张,不合法才收缩(如无重复字符最长子串)。
- 最短合法:一合法就尝试收缩,记录最小长度(如最小覆盖子串)。
易错点
计数归零时要从 map 删除还是留 0;「恰好 K」与「最多 K」的条件差一个等号。先写不变量注释,再改代码。
小结
把题目翻译成「窗口合法条件」,模板自然落地。调试时打印 left、right 与统计量,比空想边界更快。