滑动窗口是通过双指针动态维护字符串或数组中区间以高效解决子串问题的技巧。php中可用关联数组实现,适用于最长无重复子串、最小覆盖子串等场景,核心在于左右指针移动与哈希表记录字符位置或频次。

什么是字符串滑动窗口
滑动窗口是一种在字符串或数组上高效查找子串/子数组的技巧,核心是维护一个动态变化的区间(窗口),通过左右指针移动来避免重复遍历。PHP 中虽无内置滑动窗口函数,但用双指针配合哈希表(如 array)就能轻松实现,常用于解决「最长无重复子串」「最小覆盖子串」「字符串排列」「异位词」等问题。
基础实现:最长无重复字符子串
以经典问题为例:给定字符串 $s,返回其最长不含重复字符的连续子串长度。
关键思路:右指针扩展窗口,遇到重复字符时,左指针收缩直到无重复;用关联数组记录字符最新出现位置,便于快速跳转左边界。
示例代码逻辑:
立即学习“PHP免费学习笔记(深入)”;
- 初始化 $left = 0、$maxLen = 0、空数组 $seen = []
- 遍历 $right 从 0 到 strlen($s)-1
- 若 $s[$right] 已在 $seen 中,且位置 ≥ $left,则更新 $left = $seen[$s[$right]] + 1
- 更新 $seen[$s[$right]] = $right,并计算当前窗口长度 $right - $left + 1,刷新 $maxLen
进阶应用:最小覆盖子串(LeetCode 76)
给定字符串 $s 和 $t,找出 $s 中涵盖 $t 所有字符的最短子串。
需维护两个计数数组:$need($t 中各字符频次)、$window(当前窗口内频次),再用变量 $valid 记录已满足条件的字符种类数。
操作要点:
- 右移右指针,将字符加入窗口;若该字符频次达到 $need 要求,$valid++
- 当 $valid == count($need) 时,尝试收缩左边界:若当前窗口更短则更新结果;移出字符后检查是否破坏条件,及时更新 $valid
- PHP 中注意用 isset() 判断键存在,用 array_key_exists() 更稳妥(避免 null 值干扰)
实用技巧与注意事项
PHP 实现滑动窗口时容易忽略的细节:
- 字符串下标访问用 $s[$i] 即可(PHP 7.4+ 支持,兼容性好),无需 str_split 转数组
- 字符计数优先用 array,而非 stdClass 对象——索引快、内存省、写法直觉
- 窗口收缩时,左指针不是每次只挪一位,而是直接跳到重复字符上次出现位置的右边(优化时间复杂度至 O(n))
- 对大小写敏感问题,提前用 strtolower() 统一处理;含 Unicode 字符时,考虑用 mb_substr 替代单字节操作
不复杂但容易忽略。











