滑动窗口算法实战:找到字符串中所有字母异位词
题目描述: 给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。
算法思路
暴力解法需要遍历 s 的每个子串并排序比较,时间复杂度较高。更优的方案是利用滑动窗口配合哈希表(或定长数组)。
核心逻辑如下:
- 异位词的长度必须与 p 相同,因此我们在 s 上维护一个长度为 m 的滑动窗口。
- 使用两个大小为 26 的数组分别记录 p 中字符频次和当前窗口内字符频次。
- 当窗口移动时,动态更新频次统计。若某次统计结果与 p 完全一致,则记录当前起始位置。
为了进一步优化,我们可以引入一个计数器 count,仅当窗口内字符满足 p 的需求时才增加计数,从而避免每次遍历整个数组进行比较。
代码实现
以下是基于 C++ 的高效实现:
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;
int hash1[26] = {0}; // 统计 p 中字符频次
int hash2[26] = {0}; // 统计窗口中字符频次
for (auto ch : p) hash1[ch - 'a']++;
int n = s.size();
int m = p.size();
int count = 0;
for (int left = 0, right = 0; right < n; right++) {
// 进窗口
if (++hash2[s[right] - 'a'] <= hash1[s[right] - 'a']) {
count++;
}
// 窗口大小超过 m,左移
if (right - left + > m) {
(hash2[s[left] - ]-- <= hash1[s[left] - ]) {
count--;
}
left++;
}
(count == m) {
ret.(left);
}
}
ret;
}
};


