该for循环的时间复杂度:for(i = 2; i <N; i = i * i)?

时间:2017-10-03 22:22:24

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

我们现在正在了解时间复杂度,我在这个例子中遇到了很多麻烦。

for (i = 2; i < n; i = i * i)
{
     ... do something ...
}

教授说它是O(sqrt(N)),但我不确定我是否相信。毕竟,如果N = 16,它只运行2次,而不是4运行?

我的解决方案: 2 ^(2k)= N,其中k是循环运行的次数。 删除常数因子,k运行log(N)次。 我在哪里错了?感谢您就此事提出任何建议。

2 个答案:

答案 0 :(得分:4)

你的教练是错的(至少,他们的束缚不紧)你是对的,我喜欢你做过的分析,但我认为你错了最后一步的结论。

您一路上看到了所有中介价值,真是太棒了。你纠正了j所采用的值序列是2,4,16,256等。如果我们将事物重写为2的幂,请注意序列采用值

  

2 1 ,2 2 ,2 4 ,2 8 ,......

更一般地说,在循环的k次迭代之后,j的值是2 2 k (而不是2 2k ,如你最初写的)。这意味着要确定循环迭代次数,您需要确定何时

  

2 2 k = n。

在这里,您必须使用两个对数来解决此问题:

  

2 2 k = n

     

2 k = lg n

     

k = lg lg n

因此循环的迭代次数 O(log log n),低于老师给你的O(√n)和你来的O(log n)用。

对于它的价值,you often see O(log log n) behavior when you repeatedly take square roots of a number(你可以在数字O(log log n)的平方根下降到常数之前),所以它不是非常令人惊讶的是,如果你反过来运行它并保持平方值,你会看到O(log log n)出现。

答案 1 :(得分:0)

当你使用大O表示法时,你谈论的是当N进入无穷大时的行为。 N = 16不够大。

话虽如此,我认为你的教授是对的。对于循环

for (int i = 0; i*i < N; ++i) { ...}

的时间复杂度为O(sqrt(N))。

对于你的循环,你是对的,它应该是O(log(log(N)))因为循环运行时i = 2,4,16,...,2 ^ k,...其中2 ^ k&gt; = N。