题目描述

题目解析
问题定义
在字符串 s
中寻找所有满足以下条件的子串起始索引:
- 子串由
words
数组中所有单词无重复、无遗漏地串联而成 - 子串中单词顺序可任意排列
核心解题策略:滑动窗口 + 哈希表
通过滑动窗口 控制子串范围,用哈希表统计单词频次,实现高效匹配。
关键步骤解析
-
预处理阶段
- 构建基准哈希表 :用
hash1
存储 **words
**中每个单词的出现次数(作为匹配标准) - 计算关键参数 :
word_len
:单个单词长度(题目保证所有单词长度相同)window_len
:目标子串总长度 =word_len × words.size()
- 构建基准哈希表 :用
-
分组遍历策略
- 外层循环
for(int i=0; i<word_len; i++)
:- 因单词长度固定,目标子串的起始位置只能是
i, i+word_len, i+2×word_len...
- 分
word_len
组处理,覆盖所有可能的起始偏移,避免重复检查
- 因单词长度固定,目标子串的起始位置只能是
- 外层循环
-
滑动窗口匹配逻辑
- 窗口维护 :用
left
和right
指针控制窗口范围,每次移动word_len
步 - 动态哈希表 :
hash2
实时记录当前窗口内的单词频次 - 匹配计数器 :
match
统计与hash1
频次一致的单词种类数
- 窗口维护 :用
-
窗口调整规则
- 扩展窗口 :右指针右移,将新单词加入
hash2
,若频次匹配则match++
- 收缩窗口 :当窗口长度超过
window_len
时,左指针右移,移除左侧单词,若频次不匹配则match--
- 有效判断 :当
match
等于hash1
中单词种类数时,记录left
为有效起始索引
- 扩展窗口 :右指针右移,将新单词加入
完整代码实现:

复杂度分析
- 时间复杂度 :O (L×N),其中 L 为
s
长度,N 为单词长度 - 空间复杂度 :O (M),M 为
words
中单词的种类数(哈希表存储开销)