为什么时间复杂度不是O(n ^ 2),而是O(n)?
第一个循环不是n
次,第二个循环也一样,所以变成O(n*n)
,这是怎么回事?
void f(int n){
for( ; n>0; n/=2){
int i;
for(i=0; i<n; i++){
printf("hey");
}
}
}
答案 0 :(得分:6)
第一个循环不是
n
次,第二个循环也一样,所以变成O(n*n)
。
上述陈述为假,因为:
n
次。 (外部循环运行O(log n)
次,但在这种情况下没有关系。)n
的值的变化而变化。要获取此代码的时间复杂度,我们应该计算内部循环主体执行的总次数。
n
的每个值,内部循环的主体执行了n
次。n
的值由外部循环的for
语句确定。它从函数的参数值开始,每次执行外循环主体时都减半。因此,正如评论所指出的那样,由于n + n/2 + n/4 + n/8 + ... = 2n
,该算法的时间复杂度为O(n)
。
对此有一些更具体的数学证明:
找到一个整数k
,使2^(k-1) < n <= 2^k
。为此k
:
1 + 2 + 4 + ... + 2^(k-1) = 2^k - 1 >= n - 1 ∈ Ω(n)
。1 + 2 + 4 + ... + 2^k = 2^(k+1) - 1 < 4n - 1 ∈ O(n)
。因此,内部循环的总数为Θ(n)
和O(n)
。