找到字符串中所有字母异位词
题目链接:
题目描述:
给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。
题目示例:
输入:s = "cbaebabacd", p = "abc" 输出:[0, 6] 解释: 起始索引等于 0 的子串是 "cba",它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac",它是 "abc" 的异位词。
解法(滑动窗口 + 哈希表):
算法思路:
- 因为字符串 p 的异位词的长度一定与字符串 p 的长度相同,所以我们可以在字符串 s 中构造一个长度与字符串 p 的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;
- 当窗口中每种字母的数量与字符串 p 中每种字母的数量相同时,则说明当前窗口为字符串 p 的异位词;
- 因此可以用两个大小为 26 的数组来模拟哈希表,一个来保存 s 中的每个字符出现的个数,另一个来保存 p 中每一个字符出现的个数。这样就能判断两个串是否是异位词。
C++ 代码演示:
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ret;
int hash1[26] = {0}; // 统计字符串 p 中每个字符出现的次数
for(auto ch : p) hash1[ch - 'a']++;
int hash2[26] = {0}; // 统计窗口里面每个字符出现的个数
int m = p.size();
for(int left = 0, right = 0, count = 0; right < s.size(); right++) {
char in = s[right];
// 进窗口 + 维护 count
if(++hash2[in - ] <= hash1[in - ]) count++;
(right - left + > m) {
out = s[left++];
(hash2[out - ]-- <= hash1[out - ]) count--;
}
(count == m) ret.(left);
}
ret;
}
};


