思路分析:
- 使用两个数组
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; // 返回结果数组}
};