测量python脚本复杂性的问题

时间:2016-02-23 22:34:07

标签: python algorithm time-complexity

我在使用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的循环。

内部循环有三个操作(将值赋给yx*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,但如果只有一个循环,我不明白为什么存在二次项。

1 个答案:

答案 0 :(得分:1)

根据您的说法,y的最里面(program1)循环中有三条说明。

  1. 分配给y。
  2. 计算x * y。
  3. 附加到列表。
  4. 通过相同的逻辑,最外面的(x)循环中有一条指令:

    1. 分配给x。
    2. 执行inmost循环,见上文。
    3. 这会产生外循环:

      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。那是你的电话,但如果你在计算任务陈述,我会反对它。