我在使用python测量复杂性方面遇到了问题。给出接下来的两个脚本:
1 def program1(L):
2 multiples = []
3 for x in L:
4 for y in L:
5 multiples.append(x*y)
6 return multiples
1 def program3(L1, L2):
2 intersection = []
3 for elt in L1:
4 if elt in L2:
5 intersection.append(elt)
6 return intersection
在第一个中,最好的情况(运行sript的最小步骤)是两个考虑空列表L
所以只执行第二行和第六行。最佳案例场景的解决方案:2
。
在最糟糕的情况下,L
是一个很长的列表,它会在x
L
次内完成n
的循环。
内部循环有三个操作(将值赋给y
,x*y
和列表追加)。因此内循环在外循环的每次迭代中执行3*n
次。因此,嵌套循环结构执行n * (3*n + 1) = 3*n**2 + n
次。添加第二行和第六行,我们得到解决方案3n²+n+2
。
但我的问题是: 1
中的数字n(3n+1)
来自哪里?
据我所知,解决方案是n(3n)+2 = 3n²+2
与正确答案n(3n+1)+2 = 3n²+n+2
。
与此同时,在第二个案例中,最糟糕的情况是n²+2n+2
,但如果只有一个循环,我不明白为什么存在二次项。
答案 0 :(得分:1)
根据您的说法,y
的最里面(program1
)循环中有三条说明。
通过相同的逻辑,最外面的(x
)循环中有一条指令:
这会产生外循环:
n * (1 {assign to x} + n * 3 {assign, multiply, append})
或者:
n * (1 + 3n)
添加init / return指令给出:
2 + n + 3n²
在program2
中,存在类似“隐藏循环”的情况:
2 instructions for init/return, plus ...
然后运行for elt in L1
,这将是n
次迭代(n是L1的大小)。您的内部代码是if
语句。在最坏的情况下,if体总是运行。在最好的情况下,它永远不会运行。
if
条件正在测试elt in L2
,它将在L2上运行迭代函数type(L2).__contains__()
。简单的情况是 O(m)操作,其中m
是L2的长度。 L2
可能不是列表,而是in
操作不需要线性扫描的某种类型。例如,它可能是一个B树,一个字典,或一组,或谁知道什么?所以你可以假设最好的情况是elt in L2
是 O(1)而答案是否定的,而最坏的情况是elt in L2
是 O(m),答案是肯定的。
Best case: 2 + n * (1 {assign to elt} + 1 {search L2})
Best case if L2 is a list: 2 + n * (1 {assign to elt} + m {search L2})
Worst case: 2 + n * (1 {assign to elt} + m {search L2} + 1 {append})
如果L2是列表,那么 2 + 2n 最佳情况, 2 + n + nm 最佳情况, 2 + 2n + nm 强>最坏的情况。
您可能倾向于将m
视为等于n
。那是你的电话,但如果你在计算任务陈述,我会反对它。