242. Valid Anagram
On LeetCode ->Reformulated question¶
Given two strings s and t, decide whether they contain exactly the same characters with the same frequencies, possibly in different orders.
Example:
Key trick¶
Use character frequency counts.
- If lengths differ, return
Falseimmediately. - Then compare counts of each character in both strings.
Trap¶
Common mistakes:
- Forgetting the length check.
- Checking only that every character exists, but not its count.
- Sorting works, but it is slower than counting for this problem.
Why is this question interesting?¶
It tests whether you see that order does not matter, only frequencies do.
- It is a simple hash map counting problem.
- It also opens the Unicode follow-up naturally.
Solve the problem with idiomatic python¶
from collections import Counter
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# Different sizes cannot be anagrams.
if len(s) != len(t):
return False
# Same frequency table means same multiset of characters.
return Counter(s) == Counter(t)
Alternative without library:
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# Different sizes cannot be anagrams.
if len(s) != len(t):
return False
counts = {}
# Count characters from s.
for ch in s:
counts[ch] = counts.get(ch, 0) + 1
# Remove using t; fail if a character is missing/overused.
for ch in t:
if counts.get(ch, 0) == 0:
return False
counts[ch] -= 1
return True
Pytest test¶
import pytest
@pytest.mark.parametrize(
("s", "t", "expected"),
[
("anagram", "nagaram", True),
("rat", "car", False),
("a", "a", True),
("ab", "ba", True),
("ab", "aa", False),
("", "", True),
("aacc", "ccac", False),
("listen", "silent", True),
("hello", "bello", False),
],
)
def test_is_anagram(s, t, expected):
assert Solution().isAnagram(s, t) is expected
Comment my solution¶
Your solution is correct and efficient.
-
Good:
- Early length check.
- Linear time.
- Handles overuse of a character correctly.
-
Small simplification:
return Counter(s) == Counter(t)is shorter and equally clear here.
-
Test issue:
- Your test misses edge cases.
("", "")is useful in general, but LeetCode here guarantees length at least1.
from collections import Counter
import pytest
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
counts = Counter(s)
for c in t:
if counts[c] < 1:
return False
counts[c] -=1
return True
@pytest.mark.parametrize(
("s", "t", "is_anagram"),
[
("anagram", "nagaram", True),
("rat", "car", False)
]
)
def test_isAnagram(s, t, is_anagram):
assert Solution().isAnagram(s,t) == is_anagram