如果我们发现没有。对于一个数字因素,我们可以使用以下有效循环。 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");
}
答案 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)