给定两个字符串 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" 的异位词。
思路
滑动窗口+哈希,哈希表找不到的直接跳过,然后重构滑动窗口
代码
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> res;
if(p.size() > s.size())
return res;
unordered_map<char, int> hashP,hashS;
int psize = p.size();
int ssize = s.size();
for(int iter = 0; iter < psize; ++iter)
++hashP[p[iter]];
for(int iter = 0; iter < psize; ++iter)
++hashS[s[iter]];
if(hashS == hashP)
res.push_back(0);
for(int iter = psize; iter < ssize; ++iter)
{
if(hashP.find(s[iter]) != hashP.end())
{
++hashS[s[iter]];
if(--hashS[s[iter-psize]] == 0)
hashS.erase(s[iter-psize]);
if(hashS == hashP)
res.push_back(iter+1-psize);
}
else
{
if(iter<=ssize-psize)
{
++iter;
hashS.clear();
for(int i = 0; i < psize; ++i)
++hashS[s[iter+i]];
iter += psize;
if(hashP == hashS)
res.push_back(iter-psize);
--iter;
}
else
break;
}
}
return res;
}
};