繁体   English   中英

如何计算此特定算法的时间复杂度?

[英]How do I calculate Time Complexity for this particular algorithm?

我知道还有许多其他问题要求提供有关如何计算时间复杂度的一般指南,例如这个

从他们那里我了解到,当存在循环时,例如我的 Python 程序中的 (for...if...),时间复杂度为 N * N,其中 N 是输入的大小。 (如果这也是错误的,请纠正我)(在被答案纠正后编辑一次)

# greatest common divisor of two integers 

a, b = map(int, input().split())
list = []

for i in range(1, a+b+1):
  if a % i == 0 and b % i == 0:
    list.append(i) 

n = len(list)
print(list[n-1])

但是,代码的其他部分是否也会增加时间复杂度,这将使其不仅仅是简单的 O(n) = N^2? 例如,在第二个循环中,我找到了 a 和 b (a%i = 0) 的公约数,有没有办法知道计算机在找到所有除数时将执行多少机器指令,以及结果时间复杂度,在这个特定的循环中?

我希望这个问题是有道理的,如果不够清楚,请道歉。

谢谢回答

首先,一些提示:

  1. 在您的代码中没有嵌套循环。 if语句不构成循环。
  2. 并非所有嵌套循环都具有二次时间复杂度。
  3. O(n) = N*N没有任何意义:什么是n和什么是N 为什么n出现在左侧,而N出现在右侧? 您应该期望您的时间复杂度 function 取决于算法的输入,因此首先定义相关输入是什么以及您给它们起什么名字。
  4. 此外, O(n)是一函数(即那些从上面由 function f(n) = n渐近界定的函数,而f(N) = N*N一个function。由于滥用符号,我们通常写n*n = O(n)表示n*n ∈ O(n) (这是一个数学错误的陈述),但切换边( O(n) = n*n )是未定义的。数学上正确的陈述是n = O(n*n)
  5. 您可以假设所有(固定位长)算术运算都是 O(1),因为所需的处理器指令数量有一个恒定的上限。 处理器指令的确切数量与分析无关。

让我们更详细地看一下代码并对其进行注释:

a, b = map(int, input().split()) # O(1)
list = []                        # O(1)

for i in range(1, a+b+1):        # O(a+b) multiplied by what's inside the loop
  if a % i == 0 and b % i == 0:  # O(1)
    list.append(i)               # O(1) (amortized)

n = len(list)                    # O(1)
print(list[n-1])                 # O(log(a+b))

那么总体复杂性是多少? 主要部分确实是循环(之前和之后的东西可以忽略不计,复杂性方面),所以它是O(a+b) ,如果你把ab作为输入参数。 (如果您想将输入input()的长度N作为输入参数,则为O(2^N) ,因为a+b相对于N呈指数增长。)

要记住的一件事,并且您有正确的想法,那就是更高的学位优先。 所以你可以有一个恒定的 O(1) 步骤,但发生 n 次 O(N),那么它将是 O(1) * O(N) = O(N)。

您的程序是 O(N),因为唯一真正影响时间复杂度的是循环,并且如您所知,像这样的简单循环是 O(N),因为它随着 n 的增加而线性增加。

现在,如果您有一个嵌套循环,其中两个循环都随着 n 的增加而增加,那么它将是 O(n^2)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM