我正在学习课程的算法课程,我坚持这个特殊的问题。我应该找到这段代码的时间复杂性。
int sum = 0
for (int i = 1; i <= N*N; i = i*2)
{
for (int j = 0; j < i; j++)
sum++;
}
我在eclipse中检查了它,对于N的任何值,sum语句的执行次数小于N
final value of sum:
for N=8 sum=3
for N=16 sum=7
for N=100000 sum=511
因此时间复杂度应小于N. 但是给出的答案是N提升到2的力量,怎么可能?
到目前为止我做了什么:
第一个循环将运行log(N ^ 2)次,因此第二个循环将执行1,2,3 .. 2 logN
答案 0 :(得分:3)
第一个内环将是1 + 2 + 4 + 8 .. 2 ^ M,其中2 ^ M <&lt; = N * N.
2到N * N的幂之和约为2 * N * N或O(N ^ 2)
注意:当N = 100000时,N * N将溢出,因此其结果具有误导性。如果你认为溢出是问题的一部分,对于大数,总和是相当随机的,所以你可以争论它的O(1),即如果N = 2 ^ 15,N ^ 2 = 2 ^ 30并且总和将是整数.MAX_VALUE。没有更高的N值会得到更高的总和。
答案 1 :(得分:3)
这里存在很多混淆,但重要的是Big-O notation完全是关于增长率,或限制行为,正如数学家所说的那样。函数将在O(n * n)中执行意味着执行时间将比例如 n 更快地增加,但比例如 2 ^ n 慢
在使用big-O notation进行推理时,请记住常量“不计算”。在这个特定问题上有一些问题。
N*N
表达式会导致O(log n * n)复杂度... i = i*2
,导致外循环执行大约log n,如果内循环的内容在a中运行,则函数将在O(log n)中时间独立于 n 。希望这能解决问题。
答案 2 :(得分:2)
因此sum ++将执行1 + 2 + 4 + 8 + ... + N * N,总log2(N * N)次。几何级数之和1 *(1 - 2 ^ log2(N * N)/(1 - 2)= O(N * N)。
答案 3 :(得分:0)
你的外环是log(N ^ 2) - > 2 * log(N) - > log(N),你的内环是N ^ 2 / 2-> N ^ 2。因此,时间复杂度为N ^ 2 * log(N)。
关于基准测试,N = 8或N = 16的值是荒谬的,循环中的时间与设置JVM,缓存失败等相关是微不足道的。你必须:
从最大的N开始,并检查它的评估方式。
使用N的每个值进行多次运行。
认为时间复杂度是当N变得非常大时算法如何工作的度量。