While循环时间复杂度O(logn)

[英]While loop time complexity O(logn)


I cannot understand why the time complexity for this code is O(logn):

我不明白为什么这段代码的时间复杂度是O(logn):

double n;
/* ... */
while (n>1) {
     n*=0.999;
}

At least it says so in my study materials.

至少在我的学习资料里是这样说的。

3 个解决方案

#1


5  

Imagine if the code were as follows:

想象一下,如果代码是这样的:

double n;
/* ... */
while (n>1) {
     n*=0.5;
}

It should be intuitive to see how this is O(logn), I hope.

我希望能直观地看出这是O(logn)

When you multiply by 0.999 instead, it becomes slower by a constant factor, but of course the complexity is still written as O(logn)

当你乘以0。999,它会变慢一个常数因子,但当然复杂度仍然写成O(logn)

#2


5  

You want to calculate how many iterations you need before n becomes equal to (or less than) 1.

你需要计算n等于(或小于)1之前需要多少次迭代。

If you call the number of iterations for k you want to solve

如果你要求k的迭代次数你想要解决

n * 0.999^k = 1

n * 0.999 ^ k = 1

It goes like this

是这样的

n * 0.999^k = 1

n * 0.999 ^ k = 1

0.999^k = 1/n

0.999 ^ k = 1 / n

log(0.999^k) = log(1/n)

日志(0.999 ^ k)=日志(1 / n)

k * log(0.999) = -log(n)

k * log(0.999) = -log(n)

k = -log(n)/log(0.999)

k = log(n)/日志(0.999)

k = (-1/log(0.999)) * log(n)

k = (-1/log(0.999)) * log(n)

For big-O we only care about "the big picture" so we throw away constants. Here log(0.999) is a negative constant so (-1/log(0.999)) is a positive constant that we can "throw away", i.e. set to 1. So we get:

对于big- o,我们只关心“全局”,所以我们丢弃常数。这里log(0。999)是一个负数,所以(-1/log(0。999)是一个正数,我们可以把它“扔掉”,也就是设为1。所以我们得到:

k ~ log(n)

k ~ log(n)

So the code is O(logn)

代码是O(logn)

From this you can also notice that the value of the constant (i.e. 0.999 in your example) doesn't matter for the big-O calculation. All constant values greater than 0 and less than 1 will result in O(logn).

从这里,您还可以注意到常量的值(例如,本例中的0.999)对于big-O计算并不重要。所有大于0且小于1的常数都将导致O(logn)。

#3


2  

Logarithm has two inputs: a base and a number. The result of a logarithm is the power you need to raise the base to to achieve the given number. Since your base is 0.999, the number is the first smaller than 1 and you have a scalar, which is n, effectively the number of steps depends on the power you need to raise your base to achieve such a small number, which multiplied with n will yield a smaller number than 1. This corresponds to the definition of the logarithm, with which I have started my answer.

对数有两个输入:底数和数字。对数的结果是为了得到给定的数而需要的底数。因为你的基地是0.999,是第一个数量小于1和一个标量,n,有效步骤的数量取决于你的能力需要提高你的基础实现这么小的数量,数量乘以n将产生一个小于1。这对应于对数的定义,这是我的答案。

EDIT:

编辑:

Think about it this way: You have n as an input and you search for the first k where

这样想:你有n作为输入,你搜索第一个k

n * .999^k < 1

n * .999 ^ k < 1

since you are searching k by incrementing it, since if you have l >= n at a step, then you will have l * .999 in the next step. Repeating this achieves a logarithmic complexity for your multiplication algorithm.

因为你是通过递增来搜索k,如果你一步有l >= n,那么你的下一步就会有l *。999。重复此操作将使乘法算法达到对数复杂度。

关注微信公众号

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2017/09/04/ec78e40cdd8fc5aab46ea675514d42cc.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com