Find All Anagrams in a String [Medium] — Fixed Window + Freq Match
Advertisement
Problem Statement
Given strings s and p, return all start indices of p's anagrams in s.
Input: s="cbaebabacd", p="abc" → Output: [0,6]
Input: s="abab", p="ab" → Output: [0,1,2]
Intuition
Fixed window of size len(p). Compare character frequency of window with p's frequency. Track matches counter (number of chars with matching freq).
Solutions
Python
from collections import Counter
def findAnagrams(s: str, p: str) -> list[int]:
k = len(p)
if len(s) < k: return []
need = Counter(p)
window = Counter(s[:k])
matches = sum(1 for c in need if window[c] == need[c])
res = [0] if matches == len(need) else []
for i in range(k, len(s)):
# Add right char
c_in = s[i]; c_out = s[i-k]
window[c_in] += 1
if c_in in need:
if window[c_in] == need[c_in]: matches += 1
elif window[c_in] == need[c_in]+1: matches -= 1
# Remove left char
window[c_out] -= 1
if c_out in need:
if window[c_out] == need[c_out]: matches += 1
elif window[c_out] == need[c_out]-1: matches -= 1
if window[c_out] == 0: del window[c_out]
if matches == len(need): res.append(i-k+1)
return res
C++
vector<int> findAnagrams(string s, string p) {
if(s.size()<p.size()) return {};
int freq[26]={}, win[26]={};
for(char c:p) freq[c-'a']++;
for(int i=0;i<p.size();i++) win[s[i]-'a']++;
vector<int> res;
auto eq=[&](){return equal(freq,freq+26,win);};
if(eq()) res.push_back(0);
for(int i=p.size();i<s.size();i++){
win[s[i]-'a']++; win[s[i-p.size()]-'a']--;
if(eq()) res.push_back(i-p.size()+1);
}
return res;
}
Complexity
- Time: O(|s|), Space: O(1)
Advertisement