Find All Anagrams in a String
Master this topic with zero to advance depth.
Find All Anagrams in a String
Given strings s and p, return an array of all the start indices of p's anagrams in s.
Visual Representation
s = "cbaebabacd", p = "abc"
[c b a] e b a b a c d (Window: {a:1, b:1, c:1}, Matches! Index 0)
c [b a e] b a b a c d (Window: {a:1, b:1, e:1}, Mismatch)
...
c b a e b a b [a c d] (Wait, missing b! Mismatch)Examples
Level I: Brute Force
Intuition
For every possible substring of s that has the same length as p, check if it's an anagram of p. To check for anagrams, we can sort both strings or compare their character frequency maps.
Thought Process
- Iterate through
swith a loop from0ton - m(wheremisp.length()). - Extract the substring of length
m. - Compare the substring with
pusing a frequency map or sorting. - If they match, add the starting index to the result list.
Detailed Dry Run
| Start Index | Substring | Is Anagram of "abc"? | Result |
|---|---|---|---|
| 0 | "cba" | YES | [0] |
| 1 | "bae" | NO | [0] |
| 6 | "abc" | YES | [0, 6] |
Level II: Optimized Brute Force (O(N * 26))
Intuition
Instead of re-comparing the whole substring or sorting, we can compare the frequency counts of characters. Since the alphabet is small (26), comparing two maps of size 26 is , which is effectively constant time.
Thought Process
- Count character frequencies for
p. - Iterate through
sand for every window of sizem, build the frequency map for that window. - Compare the map with
pCountusingArrays.equals(Java) or==(Python/Go).
Pattern: Constant-Time Map Comparison
Level III: Optimal (Sliding Window)
Intuition
Thought Process
Since an anagram must have exactly the same length as p, we use a Fixed Size Sliding Window of length m. We maintain frequency counts for both p and the current s window. Instead of re-calculating the frequency map for every window, we 'slide' it: add the incoming character and remove the outgoing one.
Pattern: Fixed Size Sliding Window
- Init: Fill frequency maps for
pand the firstmcharacters ofs. - Slide: For
ifrommton-1:- Add
s[i]tosCount. - Remove
s[i - m]fromsCount. - Compare maps.
- Add
Detailed Dry Run
| Window | Start Index | Added | Removed | Match? | | :--- | :--- | :--- | :--- | :--- | :--- | | [0, 2] | 0 | - | - | YES | | [1, 3] | 1 | 'e' | 'c' | NO | | [6, 8] | 6 | 'c' | 'b' | YES |
⚠️ Common Pitfalls & Tips
Be careful with the sliding logic: ensure you add the NEW character and remove the OLD character at the same step to keep the window size constant. Also, check the very first window before the loop starts.
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.