滑动窗口法:
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char,int> need,window;
for(char c : p) need[c]++;
int left = 0,right = 0;
int valid = 0;
vector<int> res;
//窗口数据更新
while(right < s.size())
{
char c = s[right];
right++;
//先判断新来的在不在要求的字串中,不在的话计数不变
if(need.count(c))
{
window[c]++;
//再判断新来的字符计数是否满足条件了,满足条件数则valid++
if(window[c] == need[c])
{
valid++;
}
}
//子循环判断左窗口是否需要收缩,right-left就是当前窗口大小,因为right++导致窗口区间是[left,right)
while(right - left >= p.size())
{
//当窗口符合条件时,把起始索引加入res,记录答案
if(valid == need.size())
{
res.push_back(left);
}
char d = s[left];
left++;
//收缩后,对窗口计数更新
//先判断舍弃的在不在要求的子串中,不在的话计数不变
if(need.count(d))
{
//再判断舍弃的字符计数是否满足条件了
if(window[d] == need[d])
{
valid--;
}
window[d]--;//这里window一定要在判断后--,跟上面右移的时候反过来对称,右移是先++
}
}
}
return res;
}
};