滑动窗口是解决数组/字符串子区间问题的常用技巧,用双指针维护动态窗口,通过扩窗、缩窗和更新答案三步实现o(n)时间复杂度。

滑动窗口是什么
滑动窗口是解决**数组/字符串子区间问题**的常用技巧,核心思想是用两个指针(左右边界)维护一个动态窗口,通过移动右指针扩展、左指针收缩来满足特定条件(如和≤目标值、无重复字符等)。它把暴力O(n²)优化到O(n),因为每个元素最多进出窗口一次。
经典题型与解法要点
面试常考三类:最大/最小连续子数组和、最长无重复子串、满足条件的最短子数组。关键不在于背代码,而在于理清「何时扩窗、何时缩窗、何时更新答案」。
- 扩窗(右指针右移):一般无条件进行,把新元素纳入考虑范围
- 缩窗(左指针右移):当窗口不满足要求时(如和超限、出现重复字符),持续收缩直到合法
- 更新答案:通常在缩窗后、或每次扩窗后根据题目要求判断(如求最长就放缩窗后,求最短就放缩窗过程中)
写法模板(以PHP为例)
用while循环控制右指针,内层while处理左指针收缩。注意数组索引、边界条件(如空数组)、数据结构选择(哈希表查重、前缀和加速计算)。
$s = "abcabcbb";
$left = 0;
$maxLen = 0;
$seen = []; // 记录字符最近位置
<p>for ($right = 0; $right < strlen($s); $right++) {
$char = $s[$right];
// 如果字符已存在且在当前窗口内,移动left跳过它
if (isset($seen[$char]) && $seen[$char] >= $left) {
$left = $seen[$char] + 1;
}
$seen[$char] = $right;
$maxLen = max($maxLen, $right - $left + 1);
}容易踩的坑
PHP里尤其要注意:
立即学习“PHP免费学习笔记(深入)”;
- 字符串用
$s[$i]取字符没问题,但别误用substr()频繁截取——时间开销大 - 哈希表键名区分大小写,
isset()比array_key_exists()快,且不触发警告 - 窗口长度是
$right - $left + 1,不是$right - $left - 初始化
$left为0,但答案变量(如$minLen)要设成INF或strlen($s)+1,避免默认0干扰结果











