LeetCode Problem: Valid Anagram (LeetCode 242, Difficulty: Easy)
Question: Given two strings s and t, return true if t is an anagram of s, and false otherwise.
- Sample Input: s = "anagram", t = "nagaram"
- Expected Output: True
- Sample Input: s = "rat", t = "car"
- Expected Output: False
Questions to the interviewer:
- Can we assume the input strings only contain lower case alphabets?
- What should be the output if both strings are empty?
- If both strings are empty, we should return True as they are anagrams.
- If the lengths of the strings are not equal, they cannot be anagrams.
- Use a hash table to count the occurrence of each character in both strings, then compare the two hash tables.
- Sort both strings, then compare the sorted strings.
Approach to Solve this Problem:
- Use a hash table to count the occurrence of each character in the first string.
- Traverse the second string, for each character, if it's in the hash table, decrease the count; if it's not in the hash table or the count is zero, return False.
- In the end, if all counts in the hash table are zero, return True; otherwise, return False.
class Solution:
? ? def isAnagram(self, s: str, t: str) -> bool:
? ? ? ? if len(s) != len(t):
? ? ? ? ? ? return False
? ? ? ? ? ??
? ? ? ? counter = {}
? ? ? ? for char in s:
? ? ? ? ? ? if char in counter:
? ? ? ? ? ? ? ? counter[char] += 1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? counter[char] = 1
? ? ? ? ? ? ? ??
? ? ? ? for char in t:
? ? ? ? ? ? if char not in counter or counter[char] == 0:
? ? ? ? ? ? ? ? return False
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? counter[char] -= 1
? ? ? ? ? ? ? ??
? ? ? ? return all(value == 0 for value in counter.values())
In this code, a dictionary named counter is used to count the occurrences of each character in string s. Then, for each character in string t, if it's not in counter or its count is zero, the function returns False. If it passes through all characters in t, it will then check whether all counts in counter are zero. If so, it returns True; otherwise, it returns False. This solution uses the hash table to ensure all characters in s and t have the same frequency.
Explanation of the solution for a non-technical person:
- Imagine you have two bags of scrabble tiles. Each bag contains exactly the same set of letters, but the letters are jumbled up differently.
- If you tip out both bags and count up the number of each type of letter from each bag, the counts will match exactly if the bags initially had the same letters. This is what we mean by an anagram: two words (or sets of letters) that contain the same characters but in a different order.
- In our problem, we have two strings (think of them as our bags of letters). We count up the letters in each string and then compare these counts. If the counts are the same for all letters, we say the strings are anagrams of each other.
Explanation of the code in bullet points:
- First, we check if the two strings have the same length. If they don't, they can't be anagrams and we immediately return False.
- Then, we create a dictionary (think of it as a kind of tally chart) to count the occurrences of each character in the first string.
- Next, we go through the second string. For each character in the second string, if it's not in our dictionary or its count is zero, we return False. This means that the second string contains a character that the first string doesn't, or it contains more of a certain character than the first string does.
- Finally, if we get through the whole of the second string without returning False, we then check our dictionary. If all the counts are zero, this means that the second string used up exactly the right number of each character, so we return True. Otherwise, if there are any non-zero counts left, this means the second string didn't use up all the characters from the first string, so we return False.
- This problem is a classic example of a count comparison problem, where we need to compare the counts of individual elements in two different collections. In this case, the collections are strings and the elements are characters.
- Hash tables (dictionaries in Python) are a commonly used data structure for count comparison problems, as they allow us to efficiently store and look up counts.
The time complexity of this problem is O(n), where n is the length of the input strings. This is because we have to traverse each string once.
The space complexity is also O(n). In the worst-case scenario, each character in the string could be distinct, and we would need to store each of them in our dictionary.
Points to remember for the future:
- Remember that if two strings are anagrams, they will have exactly the same characters with the same frequencies.
- A dictionary or hashmap is useful for keeping track of character frequencies.
- Always check the lengths of the strings first. If they are not equal, they cannot be anagrams, and we can return false immediately, saving time.
- Be careful to handle characters that appear in one string but not the other.
Code explanation with sample data:
Let's take two strings, s = "anagram" and t = "nagaram" as sample data.
- if len(s) != len(t): return False: First, we check if the length of the two strings is the same. If not, they can't be anagrams, and we return False. In this case, both strings are 7 characters long, so we continue.
- count = collections.Counter(s): We use the Counter function to create a dictionary with the counts of each character in the first string. For "anagram", this gives us {'a': 3, 'n': 1, 'g': 1, 'r': 1, 'm': 1}.
- for ch in t: ...: Then we iterate over each character in the second string. For each character, we subtract 1 from its count in the dictionary. If the count becomes negative at any point, this means that the second string contains more of that character than the first string does, so we return False.
- If we get through all characters in the second string without returning False, this means that the counts match for all characters, so the strings are anagrams and we return True.
Key Python syntax for this problem:
- collections.Counter(): This is a function that generates a dictionary of counts for all distinct elements in a collection.
- for element in collection: ...: This is a for loop that iterates over each element in a collection.
- dictionary[key]: This retrieves the value associated with a particular key in a dictionary.
- if condition: return value: This is an if statement that returns a value if a condition is true.