foo = []
i = 1
while i < n:
foo= foo + ["a"]
i*=2
此代码的时间复杂度是多少? 我的主意是: while循环执行log(n)迭代。对于每次迭代,都会创建新列表 因此,总时间复杂度为:O(log ^ 2(n))。
我是对的吗?
答案 0 :(得分:4)
while
循环迭代log(n)次。
foo + ["a"]
:通过复制原始列表创建新列表。根据{{3}},复制列表需要O(n)。
时间复杂度 =&GT; 1 + 2 + 3 + ... + log(n) =&GT; (log(n)+ 1)* log(n)/ 2 =&GT;为O(log 2 n)的
我运行了timeit
:( CPython 2.7.5 64位,Windows 7)
def f(n):
foo = []
i = 1
while i < n:
foo = foo + ["a"]
i *= 2
import timeit
for n in range(20):
print n, timeit.timeit('f({})'.format(2 ** n), 'from __main__ import f')
结果:
2**0 0.187083903003
2**1 0.455513095565
2**2 0.690063737582
2**3 0.925251130713
2**4 1.16173567555
2**5 1.38232866174
2**6 1.64922777752
2**7 1.89248633685
2**8 2.14087549485
2**9 2.36934465058
2**10 2.62737119511
2**11 2.91843160213
2**12 3.19988987374
2**13 3.43422677799
2**14 3.72119850214
2**15 4.00189195846
2**16 4.31630377356
2**17 4.62789416099
2**18 4.91062905834
2**19 5.24480246883
答案 1 :(得分:2)
循环执行log(n)次迭代。
现在,假设foo = foo + ["a"]
立即复制foo
中的每个元素进行连接(而不是某些花式列表附加),那么对于每次迭代,最多也会有log(n)
个副本
是的,它是log(n)*log(n)
= log^2(n)
答案 2 :(得分:1)
让我们假设循环迭代 n 而不是log( n )次,然后数组副本需要0 + 1 + 2 + 3 + 4 + ... + n -2次操作;并且 n +2需要
0 + 1 + 2 + 3 + 4 + ... + n = 1/2· n ·( n +1)< / p>
操作。为简单起见,让我们用 m 替换 n +2,所以 n +2 = m ,因此 n = m -2,
1/2· n ·( n +1)= 1/2·( m -2)·( m -2 + 1)= 1/2·( m -2)·( m -1),
我们将在稍后使用
f( m )= 1/2·( m -2)·( m -1)。
现在因为循环的限制不是 n +2而是log( n ),所以没有
f( n +2)= 1/2·(( n +2)-2)·(( n +2 )-1)= 1/2· n ·( n +1)(见上面的发散系列)
但
f(log( n ))= 1/2·(log( n ) - 2)·(log( n ) -1)
操作,
1/2·(log 2 ( n ) - 3·log( n )+ 2)∈Ο(log 2 (名词的))。 ■