如何计算嵌套循环的时间复杂度?

时间:2018-10-31 12:40:20

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

如何计算以下算法的时间复杂度?

for(i=1;i<=n;i++)
  for(k=i;k*k<=n;k++)
   {
     Statements;
   }

据我所知,嵌套for循环的时间复杂度等于执行最里面的循环的次数。因此,这里最里面的循环执行了n*n次,因此它是O(n^2)

是否取决于第二个循环中给出的条件O(n)k*k<=n

谢谢!

1 个答案:

答案 0 :(得分:0)

算法的时间复杂度始终根据某种操作类型来衡量。例如,如果您的Statements;具有取决于n的未知时间复杂度,那么首先描述时间复杂度会产生误导。

但是您可能想知道的是根据 Statements; 操作的时间复杂度。如果Statements;是恒定时间操作,则这变得特别有意义。在这种情况下,我们所寻找的只是简单地计算执行Statements;的次数。如果此数字为3 * n,则时间复杂度将为O(n)。

要回答这个问题,让我们分开您的嵌套循环。外循环从(包括)1迭代到n,因此无论发生什么事情,它将精确地运行n次。

对于外循环的每次迭代,内循环将执行一次。它从k = i开始,并迭代直到k*k > nk > sqrt(n)。请注意,无论何时i > sqrt(n)都不会运行。我们可以看到它平均可以运行

O(sqrt(n) + sqrt(n)-1 + sqrt(n)-2 + ... + 0) / n

迭代。通过求和公式,您可以找到here,它等于

O( sqrt(n) * (sqrt(n) + 1) / 2 ) = O( (n + sqrt(n))/2 ) = O( n + sqrt(n) ) = O(n)

是的,按照您的建议,这种情况下的时间复杂度为O(n)

您可以通过编写一个简单的脚本来查看实际情况,该脚本可以模拟您的算法并计算Statements;的数量。在下面的JavaScript中,因此可以作为摘要运行:

// Simulation
function f(n) {
  let res = 0;
  for(let i=1;i<=n;i++)
    for(let k=i;k*k<=n;k++)
      ++res;
  return res;
}

// Estimation
function g(n) {
  return ~~((n + Math.sqrt(n))/2);
}

console.log(
  f(10),
  f(100),
  f(1000),
  f(10000),
);
console.log(
  g(10),
  g(100),
  g(1000),
  g(10000),
);

希望您觉得这有用。