思路分析:
- 使用两个数组
snum
和pnum
分别记录字符串s
和p
中各字符出现的次数。 - 遍历字符串
p
,统计其中各字符的出现次数,存储在pnum
数组中。 - 初始化
snum
数组,统计s
的前m-1
个字符的出现次数。 - 从第
m
个字符开始遍历s
,通过滑动窗口的方式依次判断每个子串是否为p
的同位异序子串。 - 如果当前子串的
snum
数组与pnum
数组相等,说明当前子串是p
的同位异序子串,将其起始位置加入结果数组。 - 移动滑动窗口,更新
snum
数组,继续判断下一个子串。 - 返回最终的结果数组。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
// 使用两个数组snum和pnum分别记录字符串s和p中各字符出现的次数
vector<int> snum(26, 0); // 用于记录字符串s中各字符出现的次数
vector<int> pnum(26, 0); // 用于记录字符串p中各字符出现的次数
int n = s.size(); // 字符串s的长度
int m = p.size(); // 字符串p的长度
int i, j;
vector<int> result; // 用于存储结果的数组
// 如果s的长度小于p的长度,直接返回空结果
if (n < m)
return result;
// 遍历字符串p,统计其中各字符的出现次数
for (i = 0; i < m; i++) {
pnum[p[i] - 'a']++;
}
// 初始化snum数组,统计s的前m-1个字符的出现次数
for (i = 0; i < m - 1; i++) {
snum[s[i] - 'a']++;
}
// 从第m个字符开始遍历s,依次判断每个子串是否为p的同位异序子串
for (i = 0, j = m - 1; j < n;) {
snum[s[j] - 'a']++; // 更新snum数组,加入当前字符
// 如果snum数组与pnum数组相等,说明当前子串是p的同位异序子串
if (snum == pnum)
result.push_back(i); // 将当前子串的起始位置加入结果数组
snum[s[i] - 'a']--; // 移动窗口,更新snum数组,去除窗口最左侧字符
i++; // 窗口左边界右移
j++; // 窗口右边界右移
}
return result; // 返回结果数组
}
};