# O(n) time | O(1) space
def find_anagrams(self, s: str, p: str) -> List[int]:
s_cnt, p_cnt = [0] * 26, [0] * 26
for c in s[:len(p)]:
s_cnt[ord(c) - ord('a')] += 1
for c in p:
p_cnt[ord(c) - ord('a')] += 1
res = []
if s_cnt == p_cnt:
res.append(0)
for i in range(len(p), len(s)):
s_cnt[ord(s[i]) - ord('a')] += 1
s_cnt[ord(s[i - len(p)]) - ord('a')] -= 1
if s_cnt == p_cnt:
res.append(i - len(p) + 1)
return res
- Initialization:
- First, set up two lists of size 26 (assuming lowercase English letters) to act as frequency tables for
p
and the current window in s
.
- Initialize a list result to store the starting indices of the anagrams in
s
.
- Setup:
- Count the frequency of each character in
p
and store it in the frequency table for p
.
- Count the frequency of characters in the initial window of
s
(i.e., the first len(p)
characters) and store it in the frequency table for s
.
- Sliding Window:
- Iterate from
i = len(p)
to len(s)
. For each i
:
- Compare the two frequency tables. If they are the same, the current window is an anagram of
p
, so append i - len(p)
to result.
- Slide the window: decrement the count of the character that is left behind
i - len(p)
and increment the count of the new i
character.