此功能为O(log(n))。为什么?它不是循环到n?
function fxn($n) {
for ($i = 1; $i <= $n; $i *= 2)
echo $i;
}
顺便说一句,我对O(n)分析很新。这个函数确实看起来是O(n),因为它循环到n。
答案 0 :(得分:7)
它没有循环遍历所有元素,在每一步中它跳过上一步的两倍元素 - 因为$i *= 2
部分。也就是说,假设$i
以大于零的值开始,否则它是无限循环:$i
在写入时始终为0
。
答案 1 :(得分:5)
注意:你的函数永远不会结束,因为你从0开始,0 * 2 = 0.我假设你的循环从1开始。
循环每次增加 2的倍数,这就是运行时为O(lg(n))
的原因。
让我们考虑一个简单的例子,其中n = 128。
这里是每次迭代的i值:1,2,4,8,16,32,64,128。因此,你已经经历了8个值。
lg(128) = 7 (lg = log in base 2)
= 8 - 1
请注意,- 1
是一个常量,因此它不会影响我们的运行时计算。
如果循环递增1(或任何常数,k),则运行时将为O(n)。这里要考虑的重要一点是几何系列与算术系列之间的区别,它为您提供了不同的运行时。
答案 2 :(得分:5)
这个循环是O(n):
function fxn($n) {
for ($i = 0; $i <= $n; $i++)
echo $i;
}
因为$i
采用了值:
1, 2, 3, 4, 5, 6, 7, ..., n
但是这个循环只有O(log(n)):
function fxn($n) {
for ($i = 1; $i <= $n; $i *= 2)
echo $i;
}
因为$i
采用了值:
1, 2, 4, 8, 16, 32, 64, ..., n
以这种方式增长的序列称为“对数”。
答案 3 :(得分:5)
你的代码循环到n
但不由一个(或任何常数值)循环,这将使它成为O(n)。
此就是它的作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| | | | |
+--+-----+-----------+-----------------------+
Steps 1 2 3 4
因为它每次都加倍,它实际上是O(log N),类似于二进制树搜索在每次迭代时将搜索空间减半的方式。