有:
A[1...n]
N
A
算法:
for(int i=N; i>0; i--) { // Loop 1
for(int j=1; j<N; j=j*2) { // Loop 2
for(int k=0; k<j; k++) { // Loop 3
// constant number of operations
}
}
}
我知道循环1
的时间复杂度为O(N)
。
For循环2
我会说时间复杂度为O(logN)
。
循环和3
(以及2
如果我错了)和算法的复杂性是什么?
答案 0 :(得分:6)
<强> O(N ^ 2)强>
由于j
和k
(k<j
)的相互依赖性,您无法分别考虑loop2和loop3。设N=2^m
,以简化计算。因此,j
将为1,2,4,...,2 ^(m-1),并且每次到达时loop3执行j
次。所以组合的loop2和loop3执行
1 + 2 + 4 + ... + 2^(m-1)
= 2^0 + 2^1 + 2^2 + ... + 2^(m-1)
这是Geometric Progression,等于2^m - 1 = N - 1
,即O(N)。现在抛出loop1,O(N),我们得到O(N ^ 2)。
编辑:
这是我为测试这个
而运行的perl代码print "N\tExpected\tCounted\n";
for my $N (10, 100, 1024, 8192)
{
my $count = 0;
for(my $i=$N; $i>0; $i--)
{
for(my $j=1; $j<$N; $j*=2)
{
for(my $k=0; $k<$j; $k++)
{
$count++;
}
}
}
my $expected_count = $N*$N - $N;
print "$N\t$expected_count\t$count\n";
}
输出:
N Expected Counted
10 90 150
100 9900 12700
1024 1047552 1047552
8192 67100672 67100672
请注意,除非N=2^m
,否则我们不会完全达到预期目标。
答案 1 :(得分:0)
对于k,循环执行2,4,...,N或N-1次,具体取决于N是偶数还是奇数,因此三个循环的时间复杂度为O(n logn < / EM> N)。
编辑:感谢Degustaf。我搞砸了,发现k
循环依赖于j
循环,所以for(j)循环的时间复杂度是max(O(n),O(logn))=上)。
再次编辑:考虑j
循环和k
循环作为一个整体,它执行2 + 4 + ... + N次,并且项目数是logN。
j
循环和k
循环的时间复杂度是Degustaf写的:O(N)。
我认为max(O(n),O(logn))的原因:当达到k
循环执行N次的点时,for j
循环执行了logN-1次。在之前的执行期间,k
的执行时间可以被认为是非常小的,比如N / 2,N / 4 ..,2这样的常量。所以最后的N次k
循环被认为是在j
循环执行(logN-1)次之后执行。