以下程序的Big-O表示法正确吗?

时间:2019-04-08 18:52:24

标签: python time-complexity big-o complexity-theory

我有以下三个程序,并且已经为它们计算了Big-O时间复杂度。我只想确保我做对了。

import random

def A(N):

      L=[]

      for i in range(0,26):
            L.append(chr(ord('A')+i))
      Alpha=[]
      i = 0
      while i< N:
            flag = 0
            x = random.randint(0,N-1)
            for j in range(0,i):
                  if Alpha[j] == L[x]:
                        flag = 1
                        break

            if flag == 0:
                  Alpha.append(L[x])
                  i = i + 1
      return Alpha

A(N)的复杂度为[O(1)+ O(n)+ O(n)]-> O(n ^ 2)

def A2(N):

      L=[]

      x = ord('A')
      for i in range(0,26):
            L.append(chr(x+i))
      Alpha=[]
      i = 0
      Ran = [0]*N
      while i< N:
            x = random.randint(0,N-1)
            if Ran[x] == 0 :
                  Alpha.append(L[x])
                  i=i+1
                  Ran[x]=1
      return Alpha

A2(N)的复杂度为[O(1)+ O(n)]-> O(n)

def A3(N):

      L=[]

      x = ord('A')
      for i in range(0,26):
            L.append(chr(x+i))
      Alpha=[]
      for i in range(0,N):
            Alpha.append(L[i])
      for i in range(2,N):
            x= random.randint(0,i)
            temp = Alpha[i]
            Alpha[i]= Alpha[x]
            Alpha[x] = temp
      return Alpha

A3(N)的复杂度为[O(1)+ O(n)+ O(n)]-> O(n ^ 2)

3 个答案:

答案 0 :(得分:4)

第一个示例中,复杂度为

  

[O(1)+ O(n)+ O(n)]-> O(n ^ 2)

但是它是 [O(1)+从i = 0到[O(n)]的O(n)的总和 =从i = 0到[O]的O(n)的总和(n)] = O(n ^ 2)

实际上,您执行一次O(n)任务最多n次-因此,执行O(n)次。这就是为什么这实际上是一个乘法。


第二个示例中,如果循环的执行不依赖于随机数,那将是正确的-感谢Nick Vitha指出了这一点,请参阅his answer-但是,不幸的是。

算法时间复杂度通常应用于确定性算法,在这里我们谈论的是概率算法,该算法以different way为模型。 在这种情况下,获取复杂度类并非易事,因为它取决于随机函数的实现及其分布。

您的randomized algorithm既不能保证成功,也不能保证运行时间有限,因此应该不确定复杂度类 ,但是需要随机证明。而且,考虑到随机函数的分布,时间复杂度的期望值应该更容易计算。


在第三个示例中,它确实是

  

[O(1)+ O(n)+ O(n)]

但是当您将相似的类加在一起时,您将得到同一类的时间复杂度-这是因为您将获得初始复杂度的倍数,在渐近上下文中它等于它。 因此解决方案是:

[O(1)+ O(n)+ O(n)]-> O(n)


如果从数学上讲我的表达方式不准确,我深表歉意,但我相信它足以概括该概念。

答案 1 :(得分:0)

1。

  

A(N)的复杂度为[O(1)+ O(n)+ O(n)]-> O(n ^ 2)

这是不正确的。好吧,O(n ^ 2)部分是正确的,但是如何实现却不正确。

[O(1)+ O(n)+ O(n)]-> O(2n +1)-> O(n)

但是,您的代码是:

[O(k)+ O(n)* O(n)]-> O(n ^ 2 + k)-> O(n ^ 2)

其中k是一个常数(在这种情况下为26,但是只要它不受n的影响就没有关系)。您这样嵌套的东西。您可以根据需要将O(k)简化为O(1)。无论哪种方式,它都会消失。

2。

  

A2(N)的复杂度为[O(1)+ O(n)]-> O(n)

哦,天哪。我什至不知道从哪里开始。

因此,基本上,您正在访问长度为N的数组的随机部分。您正在检查它是否为0。如果是0,则进行一些操作并将其分配给1。

我倾向于认为,对此的答案将平均高于O(n)。拥有更多咖啡和/或数学经验的人可能需要对此有所了解,但是您将至少循环n次,并且在最差时,该循环将是无限的,因为您正在进行随机访问,并且可以保持随机检查一个数字1。通常,您使用WORST进行O()表示法,因此此循环为

O(无穷大)-> 未定义

3。

  

A3(N)的复杂度为[O(1)+ O(n)+ O(n)]-> O(n ^ 2)

如前所述,它是 [O(1)+ O(n)+ O(n)],但是得出 O(n)

答案 2 :(得分:0)

对于A2,我同意尼克的观点,即它不受限制(最坏的情况)。您的平均情况是n * Log(n)。您的O(n)实际上是最好的情况。