在Python

时间:2018-12-31 23:08:22

标签: python algorithm data-structures time-complexity

我开始学习数据结构和算法,但是遇到了一个问题。这是我正在测试的功能:

def create_list_with_concat(n):
    l = []
    for i in range(n):
        l = l + [i]

这是我的思考过程: 我知道concat运算符是O(k),其中k是要添加到原始列表中的列表的大小。由于在这种情况下k的大小始终为1,因为我们一次添加了一个字符列表,因此concat操作需要执行1步骤。由于循环迭代n次,因此该算法将执行n个步骤-每次迭代执行1个步骤。因此,该算法的时间复杂度为O(n)。该算法的实际执行时间类似于T(n) = dn,其中d是执行级联所花费的时间。对于这样的功能,我希望以下内容是正确的:当您将输入大小增加10倍时,由于以下原因,输出(执行时间)将增加10倍:

(x, dx) --> (10x, 10dx) --> 10dx/dx = 10

但是,当我实际测试算法的实际值并计时执行时间时,这似乎没有发生。相反,当我将输入大小增加10倍时,输出(执行时间)将增加100倍,而当我将输入大小增加100倍时,输出将增加10000倍。这些输出建议一个二次时间函数和O(n squared)

这是我的完整代码:

import timeit
def create_list_with_concat(n):
    l = []
    for i in range(n):
        l = l + [i]

t1 = timeit.Timer("create_list_with_concat(100)", "from __main__ import 
create_list_with_concat")
print("concat ",t1.timeit(number=1)*1000, "milliseconds")
t1 = timeit.Timer("create_list_with_concat(1000)", "from __main__ 
import create_list_with_concat")
print("concat ",t1.timeit(number=1)*1000, "milliseconds")
# OUTPUT
# concat  0.05283101927489042 milliseconds
# concat  2.8588240093085915 milliseconds

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:5)

时间复杂度不是O(N)

两个列表A和B的concat操作的时间复杂度为O(A + B)。这是因为您不是要添加到一个列表中,而是要创建一个全新的列表,并使用A和B中的元素填充它,这需要您遍历两个列表。

因此,进行l = l + [i]的操作是O(len(l)),而您需要进行N的操作N的步骤,导致总体复杂度为O(N^2)

您将concat与appendextend函数混淆了,该函数不会创建新列表而是将其添加到原始列表中。如果使用这些功能,则时间复杂度的确为O(N)

附加说明:

符号l = l + [i]可能会造成混淆,因为从直观上看,[i]似乎只是被添加到现有的l中。这不是真的!

l + [i]建立一个全新的列表,然后l指向该列表。

另一方面,l += [i]修改了原始列表,其行为类似于extend

答案 1 :(得分:3)

  

这是我的思考过程:我知道concat运算符是 O(k),其中 k 是要添加到原始列表中的列表的大小。由于在这种情况下 k 的大小始终为1,因为我们一次添加了一个字符列表,所以concat操作需要1步。

此假设为不正确。如果您写:

l + [i]

您构造了一个新列表,该列表将包含 m + 1 个元素,其中{em> m 是l中元素的数量,前提是已实现列表像数组一样,我们知道构造这样的列表将花费 O(m)时间。然后,将 new 列表分配给l

所以这意味着步骤总数为:

 n
---
\              2
/    O(m) = O(n )
---
m=0

所以时间复杂度是 O(n 2

不过,对于l += [i]和{{1,您都可以使用l.append(i)或什至更快的l += [i]来提高性能,其中摊销成本是}} O(1),因此算法为 O(n),但是l.append(i)可能会更快一些,因为我们节省了构造一个新列表等。

答案 2 :(得分:2)

Void My_func(Some_struct*** array)
    { //Code}

使列表变异和创建新列表之间的复杂度有所不同。