找到字符串中所有字母异位词
题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。异位词指由相同字母重排列形成的字符串。
解题思路
这道题的核心在于利用滑动窗口配合哈希表来高效判断字符频次是否匹配。
- 窗口大小固定:因为异位词的长度必须等于 p 的长度,所以我们在 s 上维护一个长度为 m(p 的长度)的滑动窗口。
- 频次统计:使用两个大小为 26 的数组模拟哈希表。
hash1记录 p 中每个字符的出现次数,hash2记录当前窗口内字符的出现次数。 - 动态维护:随着右指针向右移动,更新窗口内的字符计数;当窗口长度超过 m 时,左指针右移,移除旧字符的影响。
- 匹配判断:为了减少每次遍历比较两个数组的开销,我们引入一个变量
count来记录当前窗口中'满足要求'的字符数量。当count等于 p 的长度时,说明找到了一个异位词。
代码实现
下面是经过优化的 C++ 实现,重点在于如何精简地维护 count 变量。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;
int hash1[26] = {0}; // 记录 p 中字符频次
int hash2[26] = {0}; // 记录窗口中字符频次
for (char 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++) {
char in = s[right];
// 进窗口:增加计数
(++hash2[in - ] <= hash1[in - ]) {
count++;
}
(right - left + > m) {
out = s[left++];
(hash2[out - ]-- <= hash1[out - ]) {
count--;
}
}
(count == m) {
ret.(left);
}
}
ret;
}
};


