NeetCode Blind75: #2 — Valid Anagram
Today I’m tackling the next NeetCode Blind75 problem: Valid Anagram.
Problem
Given two strings s
and t
, the task is to return true
if they are
anagrams of each other, and false
otherwise.
Pretty simple in theory: both strings should contain the same letters in the same frequency, just potentially in a different order.
My Solutions
I wrote three implementations and tested them all against the same inputs to make sure the logic was sound. Here’s what I tried:
1. is_anagram_hash
This builds two separate hash tables and compares them. It’s conceptually simple, but requires space for two dictionaries.
def is_anagram_hash(s1: str, s2: str) -> bool:
hash1 = dict()
hash2 = dict()
for letter in s1:
increment_letter(hash1, letter)
for letter in s2:
increment_letter(hash2, letter)
return hash1 == hash2
2. is_anagram_hash_optimized
Instead of creating two dictionaries, this one uses a single hash and updates counts in-place. The first loop over the first string increments counts; the second decrements. If any value isn’t zero by the end, the strings aren’t anagrams.
def is_anagram_hash_optimized(s1: str, s2: str) -> bool:
hash = dict()
for letter in s1:
update_letter(hash, letter, UpdateMode.INCREMENT)
for letter in s2:
update_letter(hash, letter, UpdateMode.DECREMENT)
for letter in hash:
if hash[letter] != 0:
return False
return True
3. is_anagram_sorted
This one just sorts both strings and compares them. It’s dead simple and surprisingly effective — and usually fast enough.
def is_anagram_sorted(s1: str, s2: str) -> bool:
return sorted(s1) == sorted(s2)
The optimized hash version is probably the best in terms of time and space, trade-off, assuming the character set is constrained (as it is here to lowercase letters). But the sorted approach is hard to beat for readability.
All three passed the same suite of tests.