为什么下面的代码在时间复杂度方面被认为是低效的,我该如何改进它?ia in n的时间复杂度为o(n),因此问题出现了。
我累了什么?我最初排序了n,a和B,但性能没有变化。
客观,求h-m之和注:len(a)始终等于len(B)
n=[1, 5, 3] #//can be with 100K+ items
a=set([3,1]) #//can be with 50K+ items
b=set([5,7])
h=0
m=0
for ia, ib in zip(a,b):
if ia in n:
h+=1
if ib in n:
m+=1
print (h-m)
编辑:我意识到仅仅讨论概念是不够的,比如为什么它被认为是低效的,而没有明确地解决时间/空间复杂性。我相应地改变了问题。
3条答案
按热度按时间js81xvg61#
由于
n
是一个list
,而且它非常大(超过10万个条目),因此每个if WHATEVER in n:
都在做O(n)
的工作,涉及超过10万个相等性检查。基本上你的类型是反着来的你使用
set
来做你迭代的事情(作为set
除了可能从你的输入中删除重复之外,可以节省一点),使用list
来做你的成员测试(O(n)
包含检查在大型list
上比O(1)
包含检查在任何大小的set
上要昂贵得多)。假设
n
的元素是可散列的,在循环之前将它们转换为set
,并对set
使用包含测试:注意,
zip
ing除了可能从被迭代的元素中排除一些元素之外什么也不做; iflen(a) != len(b)
,则无法检查迭代长度超过最短set
的元素。如果要计算所有元素,最简单的解决方案是拆分循环,将单个循环替换为:fv2wmkja2#
这里有一个简单的方法-使用
set.intersection
-并且不使用for
循环或zip
函数:x9ybnkn63#
推测一下,
if x in y
测试是最慢的,把a和b作为集合可能没有多大帮助--你只是在压缩和枚举,但是如果n是一个集合,那么成员资格测试可能会更快。可能没有必要压缩,因为你似乎没有对ia和ib做任何事情,使它们交互,但我怀疑这会引入很多开销。