我现在两次采访中听到了以下问题:
给定一长串字符串,str_list和目标字符串,如果目标字符串是str_list中任何单词的字谜,则返回True
(假设有多个查询是可能的,所以我们不希望有早期退货或w / e的解决方案)
我已经实现了两次以下解决方案,我认为是O(NM),其中N是str_list的长度,M是str_list中最长字的长度。
def is_anagram(str_list,target):
anagrams = set()
#O(N)
for s in str_list:
#O(M)
anagrams.add(frozenset(Counter(string).items()))
#O(len(target), but we could just check length vs. longest str in str_list, so O(M))
return frozenset(Counter(target).items()) in anagrams
##Total = O(N*M)
每次他们告诉我这是不错的,但我可以使用以下版本做得更好,使用排序:
def sorted_is_anagram(str_list,target):
#O(N)
for i,string in enumerate(str_list):
#MLog(M)
str_list[i] = "".join(sorted(string))
#O(M*NLogN)
str_list = set(sorted(str_list))
#O(M(Log(M)))
return "".join(sorted(target)) in str_list
##Total = O(N*MLog(M) + M*NLogN)
我疯了还是他们的版本根本不是更好?我搞砸了什么?
谢谢!
答案 0 :(得分:1)
你可能误解了这个问题。通常,问题涉及一次给出大量字符串,然后针对该组字符串存在多个查询。因此,例如,您可能会获得一个包含250,000个英语单词的列表作为您的字符串集。然后,针对该列表将有数百万个查询。
解决方案涉及两个部分。首先,您创建一个字典,其中包含已排序的anagram作为其关键字。该值是可以由这些字母组成的单词列表。所以,给出“list”和“silt”这两个词,你就得到了:
{key="ilst", value={"list","silt"}}
您保存生成的字典,以便可以跨调用使用它。
现在,当某人进行查询时,您可以对给定单词中的字母进行排序,在字典中查找,然后使用字谜回复。
如果你给了N个平均长度为M的单词,那么构建字典就是O(N *(M log M))。但这是一次性成本。
每个查询都要求您对传递的单词中的字母进行排序,这也是O(M log M)。但字典查找是O(1)。因此K查询的成本是O(K *(M log M))。