题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示:
1<=s.length,p.length<=3∗1041 <= s.length, p.length <= 3 * 10^41<=s.length,p.length<=3∗104
s 和 p 仅包含小写字母
思路
1 特殊判断 ,如果s的长度小于p的长度,直接返回空。
2 计算p中每个字符的数量 。
3 s用滑动窗口 ,每次向右滑动一格 ,并获取这个窗口中每个字符的个数,如果和p的字符个数答案相同,记录下来即可。
4 每次判断是否相等只需要判断26个字符数量,时间复杂度为o(n * 26)。
代码
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
int slen = s.size(), plen = p.size();
// 特殊情况处理
if(slen < plen) return vector<int>();
// ans存储答案
vector<int>ans;
// num记录p, s中每个字符的个数
vector<int>nump(26, 0);
vector<int>nums(26, 0);
// 统计p中每个字符的个数, 同时记录s的前p.len个
for(int i = 0; i < plen; ++i)
{
++nump[p[i] - 'a'];
++nums[s[i] - 'a'];
}
// 第一组相同先记录下
if(nump == nums)
{
ans.push_back(0);
}
// 每次向右滑动一次, 对比是否相同
for(int i = plen; i < slen; ++i)
{
++nums[s[i] - 'a'];
--nums[s[i - plen] - 'a'];
if(nump == nums)
{
ans.push_back(i - plen + 1);
}
}
return ans;
}
};