查找函数时间复杂度的准确方法

时间:2019-03-02 23:13:20

标签: c for-loop time-complexity

如何查找此函数的时间复杂度:

代码

void f(int n)
{
    for(int i=0; i<n; ++i)
        for(int j=0; j<i; ++j)
            for(int k=i*j; k>0; k/=2)
               printf("~");
}

我根据直觉对(n^2)*log(n)进行了有根据的猜测,结果证明是正确的。

但是我似乎找不到确切的解释。

1 个答案:

答案 0 :(得分:0)

对于ii>0的每个值,内循环将有i-1个值,k的每个值分别从以下位置开始:

i*1, i*2, ..., i(i-1)

由于k除以2直到达到0,所以每个这些内部-内部循环都需要lg(k)个步骤。因此

lg(i*1) + lg(i*2) + ... + lg(i(i-1)) = lg(i) + lg(i) + lg(2) + ... + lg(i) + lg(i-1)
                                     = (i-1)lg(i) + lg(2) + ... + lg(i-1)

因此总数为

f(n) ::= sum_{i=1}^{n-1} i*lg(i) + lg(2) + ... + lg(i-1)

现在从上方绑定f(n+1)

f(n+1) <= sum_{i-1}^n i*lg(i) + (i-1)lg(i-1)
       <= 2*sum_{i-1}^n i*lg(i)
       <= C*integral_0^n x(ln x)            ; integral bound, some constant C
        = C/2(n^2(ln n) - n^2/2)            ; integral x*ln(x) = x^2/2*ln(x) - x^2/4
        = O(n^2*lg(n))

如果我们现在从下面绑定f(n+1)

f(n+1) >= sum_{i=1}^n i*lg(i)
       >= C*integral_0^n x(ln x)            ; integral bound
        = C*(n^2*ln(n)/2 - n^2/4)           ; integral x*ln(x) = x^2/2*ln(x) - x^2/4
       >= C/4(n^2*ln(n))
        = O(n^2*lg(n))