Find All Anagrams in a String - Solution
Solutions and explanations

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        freq_p = Counter(p)
        freq_win = Counter(s[: len(p) - 1]) # initialize window except last char
        res = []
        left = 0
        
        for right in range(len(p) - 1, len(s)):
            # Add the right character to the window
            freq_win[s[right]] += 1

            # Compare current window with target (compares at most 26 letters)
            if freq_win == freq_p: 
                res.append(left)
            
            # Remove the left character to slide the window
            freq_win[s[left]] -= 1
            left += 1
        return res       

Complexity Analysis

Here, n is the length of the string s, and m is the length of string p.

  • Time Complexity: O(n + m)
    • Building the initial frequency map for string p takes O(m) time.
    • Sliding Window: The sliding window runs for n - m + 1 steps. Each step involves updating the map and checking for equality, which takes O(26) time. Since 26 is a constant, this simplifies to O(n).
  • Space Complexity:
    • Auxiliary Space: O(1) - Fixed-size frequency maps (up to 26 characters) are used, independent of input size.
    • Output Space: O(n) - In the worst case (where every possible substring of length m is an anagram of p), the result list may store up to n - m + 1 starting indices.