最近我在Hackerrank上尝试解决这个问题。最终我得到了以下解决方案,可以在规定的时间限制内得出正确答案:
from collections import Counter
lisa=[]
for each in range(input()):
current=raw_input()
count=0
lookup_dict={}
i=0
for i in range(len(current)):
for j in range(i,len(current)):
sub_string=current[i:j+1]
sub_string=''.join(sorted(sub_string))
if sub_string in lookup_dict.keys():
lookup_dict[sub_string]+=1
else:
lookup_dict[sub_string]=1
for k in lookup_dict.values():
count+=k*(k-1)/2
print count
我的问题是,他们提供的解决方案(如下所示)比我编写的要快得多,尽管使用的复杂度和方法相同。
from collections import *
for i in range(input()):
s = raw_input()
check = defaultdict(int)
l = len(s)
for i in range(l):
for j in range(i+1,l+1):
sub = list(s[i:j])
sub.sort()
sub = "".join(sub)
check[sub]+=1
sum = 0
for i in check:
n = check[i]
sum += (n*(n-1))/2
print sum
我猜测这与defaultdict
方法有关,但是不知道为什么?
defaultdict
部分,然后再次检查所花费的时间。此外,在每个循环中你正在计算len(current)
,第二个示例缓存该值,因为它不会改变。 - Hacketolookup_dict.keys()
替换为lookup_dict
,看看对速度的影响。 - Kevinfrom collections import defaultdict
,这更符合 Python 的风格。 - SuperBiasedMan.keys()
会立即生成完整的列表,而in dict
检查每个值。 - SuperBiasedMankeys()
的时间复杂度是O(n),其中n是字典中元素的数量。x in dict
的时间复杂度为O(1),因此对于大型字典来说,它往往具有更好的性能。 - Kevin