我们现在正在了解时间复杂度,我在这个例子中遇到了很多麻烦。
for (i = 2; i < n; i = i * i)
{
... do something ...
}
教授说它是O(sqrt(N)),但我不确定我是否相信。毕竟,如果N = 16,它只运行2次,而不是4运行?
我的解决方案: 2 ^(2k)= N,其中k是循环运行的次数。 删除常数因子,k运行log(N)次。 我在哪里错了?感谢您就此事提出任何建议。
答案 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。