C 求函数时间复杂度的精确方法
如何找到此函数的时间复杂度: 代码C 求函数时间复杂度的精确方法,c,for-loop,time-complexity,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("~"); } void f(int n) { 对于(int i=0;i对于i,i>0,将有i-1内环值,分别从以下位置开始计算k: i*1, i*2, ..., i(i-1)
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("~");
}
void f(int n)
{
对于(int i=0;i对于i
,i>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))
对于i
,i>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))
似乎唯一困难的部分是如何处理k=i*j
。这可以通过意识到log(n^2)=2log(n)
和big-O忽略常量来处理。的确,我注意到了这些事情,但正如你所说,ij部分令人困惑。最内部的循环执行log(ij)次,所以我们这里有某种总和,我似乎无法准确地表达出来,我明白。你在寻找精确的公式,比如1+2+3+…+n=n(n+1)/2
。我不确定这段代码是否有这样一个公式,但你可以试试运气。看起来唯一困难的部分是如何处理k=I*j
。这可以通过实现log(n^2)=2log(n)来处理
而big-O忽略常量。确实如此,我注意到了这些事情,但问题是,正如你所说,ij部分令人困惑。最里面的循环执行log(ij)次,所以我们这里有某种总和,我似乎无法准确地表示出来,我明白。你在寻找精确的公式,比如1+2+3+…+n=n(n+1)/2
。我不确定这段代码是否有这样的公式,但你可以试试运气。