循环运行日志时间时的复杂性

时间:2015-04-10 08:31:34

标签: algorithm for-loop time-complexity

如果我们发现没有。对于一个数字因素,我们可以使用以下有效循环。 for(i = 1; i< = sqrt(n); i ++),其中n是' no'其中的因素有待找到。该循环将具有O(n)的复杂度。

以下代码段的时间复杂度是多少? (假设log(x)返回基数2中的日志值)。 O(n ^ 2)还是O(n logn)? (我假设log n是循环除以2时的复杂性。即i / = 2)

void fun()
{
    int i,j;
    for(i=1;i<=n;i++)
        for(j=1;j<=log(i);j++)
            printf("hello world");
}

4 个答案:

答案 0 :(得分:1)

代码中“Hello world”打印的实际数量为:

然后,您可以使用Srinivasa Ramanujan approximation的log(n!):

获得整个代码的实际复杂性,即O(n logn)

答案 1 :(得分:0)

对于范围printf中的log(i),内部循环调用i大约[1..n]次。通话总数约为

log(1)+log(2)+log(3)+...log(n) = log(n!)

现在,斯特林渐近公式将为您提供解决方案。


对于基数2的对数,确切的计数由

给出
0 + 1 + 1 + 2 + 2 + 2 + 2 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + ... + floor(Lg(n))

1.0 + 2.1 + 4.2 + 8.3 + ... + k.floor(Lg(n))

为方便起见,假设n的格式为n=2^m-1,以便上次运行完成(以及k=2^(m-1))。

现在将x^k的总和从0加到m-1,等于(x^m-1)/(x-1),并导出x得到x^k.k的总和}。评估x=2,即可获得

s = m.2^m-2^m+2 = (n+1).Lg(n+1)-n+1

对于其他n,您需要为最后一次部分运行添加更正字词。使用m=floor(Lg(n+1))

t = m.(n+1-2.2^m)

答案 2 :(得分:0)

可以证明O(n * Log(n))的上限而无需任何数学运算。

void fun()
{
   int i,j;
   for(i=1;i<=n;i++)
       for(j=1;j<=log(n);j++)    // << notice I changed "i" to "n" 
           printf("hello world");
}

上面的函数将运行N次内部循环,并且内部循环将运行log(N)次。

因此,该函数将准确地运行 nLog(n)次。

自此功能

 (log(n) + log(n) + ... + log(n)) // n times 

大于OP版本

(log(1) + log(2) + ... + log(n))

然后它是原始版本的上限。

<= O(n log(n)

评论

(log(n) + log(n) + ... + log(n)) // n times
= log(n^n)
= n*log(n)

答案 3 :(得分:0)

j依赖于j,因此展开依赖关系,意味着仅分析i

如果i=1 ---->内部循环执行log(1)

如果i=2 ---->内部循环执行log(2)

如果i=3 ---->内部循环执行log(3)

如果i=n ---->内部循环执行log(n)次。

将它们组合==> log(1)+log(2)+.....+log(n) = log ( 1.2.3...n ) = log ( n! ) = n log(n)