Master all anagram-related problems — checking if two strings are anagrams, grouping anagrams together, finding all anagram substrings in a text (sliding window), minimum characters to form anagram, and the frequency array optimization for fixed alphabets.
What Is an Anagram?
Two strings are anagrams if one is a rearrangement of the other — they contain the same characters with the same frequencies.
| "listen" and "silent" | anagrams |
| "anagram" and "nagaram" | anagrams |
| "hello" and "world" | not anagrams |
2. Group Anagrams Together
from collections import defaultdict
def group_anagrams(strs):
"""
Group strings that are anagrams of each other.
Key: sorted string (canonical form). O(n × m log m)
"""
groups = defaultdict(list)
for s in strs:
key = tuple(sorted(s)) # "eat" → ('a','e','t')
groups[key].append(s)
return list(groups.values())
def group_anagrams_fast(strs):
"""
Faster key: char count array. O(n × m)
"""
groups = defaultdict(list)
for s in strs:
count = [0] * 26
for c in s: count[ord(c) - ord('a')] += 1
key = tuple(count) # (1,0,0,...,1,...) for "aet"
groups[key].append(s)
return list(groups.values())
print(group_anagrams(["eat","tea","tan","ate","nat","bat"]))
# [['eat','tea','ate'], ['tan','nat'], ['bat']]
3. Find All Anagrams in a String — Sliding Window
def find_anagrams(s, p):
"""
Return all start indices of anagrams of p in s.
Sliding window with frequency comparison. O(n) time.
"""
result = []
if len(p) > len(s):
return result
p_count = Counter(p)
window = Counter(s[:len(p)]) # Initial window
if window == p_count:
result.append(0)
for i in range(len(p), len(s)):
# Add new right character
window[s[i]] += 1
# Remove leftmost character
left_char = s[i - len(p)]
window[left_char] -= 1
if window[left_char] == 0:
del window[left_char]
if window == p_count:
result.append(i - len(p) + 1)
return result
print(find_anagrams("cbaebabacd", "abc")) # [0, 6]
print(find_anagrams("abab", "ab")) # [0, 1, 2]
Optimized — Track Difference Count
def find_anagrams_v2(s, p):
"""
More efficient: track 'differ' count instead of full comparison.
"""
result = []
n, m = len(s), len(p)
if n < m: return result
p_freq = [0] * 26
w_freq = [0] * 26
for c in p: p_freq[ord(c)-97] += 1
for c in s[:m]: w_freq[ord(c)-97] += 1
differ = sum(1 for i in range(26) if p_freq[i] != w_freq[i])
if differ == 0: result.append(0)
for i in range(m, n):
# Add right character
r = ord(s[i]) - 97
if w_freq[r] == p_freq[r]: differ += 1
w_freq[r] += 1
if w_freq[r] == p_freq[r]: differ -= 1
# Remove left character
l = ord(s[i-m]) - 97
if w_freq[l] == p_freq[l]: differ += 1
w_freq[l] -= 1
if w_freq[l] == p_freq[l]: differ -= 1
if differ == 0: result.append(i - m + 1)
return result
4. Minimum Characters to Make Anagram
def min_steps_to_anagram(s, t):
"""
Minimum characters to change in s to make it an anagram of t.
"""
freq_s = Counter(s)
freq_t = Counter(t)
changes = 0
for char in freq_t:
diff = freq_t[char] - freq_s.get(char, 0)
if diff > 0:
changes += diff
return changes
print(min_steps_to_anagram("leetcode", "practice")) # 5
print(min_steps_to_anagram("anagram", "mangaar")) # 0
5. Palindrome Permutation Check
def can_form_palindrome(s):
"""
Check if any permutation of s can be a palindrome.
At most one character can have odd frequency.
"""
freq = Counter(s)
odd_count = sum(1 for count in freq.values() if count % 2 != 0)
return odd_count <= 1
print(can_form_palindrome("aab")) # True — "aba"
print(can_form_palindrome("code")) # False
print(can_form_palindrome("carerac")) # True — "racecar"
Pattern Summary
| Problem | Technique | Time | Space |
|---|
| Is anagram? | Counter comparison | O(n) | O(1)* |
| Group anagrams | Sorted key hash map | O(nm log m) | O(nm) |
| Find anagram substrings | Sliding window | O(n) | O(1)* |
| Min changes for anagram | Counter difference | O(n) | O(1)* |
| Can form palindrome | Count odd frequencies | O(n) | O(1)* |
*O(1) space when alphabet size is fixed (26 lowercase letters)
*Next: String Interview Problems*
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Anagram Problems — Detection, Grouping, and Sliding Window Variations.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Data Structures & Algorithms topic.
Search Terms
data-structures-algorithms, data structures & algorithms, data, structures, algorithms, strings, anagram, problems