1.4 Write a method to decide if two strings are anagrams or not.
This "easy" problem really taught me a lesson. Firstly, I quickly came up with a somewhat smart solution:
If we use quick sort, the solution above takes O(nlgn) running time. Andthen... I stopped!
So bad. I have seen so many problems and most of them have time complexity of O(nlgn) and cannot be improved further. So I naturally set O(nlgn) as my final goal. However, when I turned to the answer page, I found a better solution: if we sacrifice space, we can achieve O(n). The code below is my implementation based on the same thought as standard answer:
I will keep it in mind: there is no perfect solution, and there always exists a better solution!
This "easy" problem really taught me a lesson. Firstly, I quickly came up with a somewhat smart solution:
import string
def are_anagrams(str1, str2):
# To change a string, we have to convert it to a list first
str1_list = [i for i in str1]
str2_list = [i for i in str2]
# Sort the two lists
str1_list.sort()
str2_list.sort()
# Convert back to strings for comparison
str1 = string.join(str1_list)
str2 = string.join(str2_list)
# Compare the sorted strings
return str1 == str2
If we use quick sort, the solution above takes O(nlgn) running time. Andthen... I stopped!
So bad. I have seen so many problems and most of them have time complexity of O(nlgn) and cannot be improved further. So I naturally set O(nlgn) as my final goal. However, when I turned to the answer page, I found a better solution: if we sacrifice space, we can achieve O(n). The code below is my implementation based on the same thought as standard answer:
def are_anagrams2(str1, str2):
if len(str1) != len(str2):
return False
flags = [0 for i in range(0, 256)]
for i in range(0, len(str1)):
index1 = ord(str1[i])
index2 = ord(str2[i])
# One occurrence of a letter in str1
# makes the corresponding flag increase by one
flags[index1] = flags[index1] + 1
# One occurrence of a letter in str2
# makes the corresponding flag decrease by one
flags[index2] = flags[index2] - 1
# If there exist a flag that is not 0, the two strings are not anagrams
for i in range(0, 256):
if flags[i] != 0:
return False
return True
I will keep it in mind: there is no perfect solution, and there always exists a better solution!