我无法弄清楚以下代码片段的时间复杂性:
void f( int N ){
sum ++;
if ( N > 1){
f( N /2);
f( N /2);
}
这是给我带来问题的双重迭代。
我知道(或认为)
的时间复杂性void f( int N ){
sum ++;
if ( N > 1){
f( N /2);
}
是~log2(N),但不知道如何处理其他代码。
答案 0 :(得分:3)
您在(N/2)
上调用了两次递归。让我们写下公式:
T(n) = 2*(N/2) + 1
使用master theorem,我们会遇到第一种情况:
T(n) = Θ(n)
我们还发现 T(n)= 2 * T(n / 2)+ 1 here,这表明它受O(n)
答案 1 :(得分:3)
解决这个问题的好方法是:
1。查找重现关系
对于f
的每次通话,我们都有时间复杂度T(N)
。每个电话都包含:
C
:sum++
,比较N > 1
,递归调用开销等。f
的2次递归调用,每次调用时间复杂度为T(N / 2)
。因此递归关系由T(N) = 2T(N/2) + C
给出。
2。通过检查找到解决方案
如果我们反复将T(N)
替换为自己,我们可以看到一种新兴模式:
求和的上限是m
?由于停止条件为N > 1
,因此在重复替换之后,要求将是
因此求和等于(放下舍入和常量C
,因为它只是乘法):
3。通过归纳证明
因此,通过归纳,求和结果是正确的,T(N)
确实是Ө(N)
。
4。数值测试:
如果需要,我们可以编写代码来确认我们的结果:
function T(n) {
return n > 1 ? 2 * T(floor(n/2)) + 1 : 1;
}
结果:
N T(N)
-------------------------
2 3
4 7
8 15
16 31
32 63
64 127
128 255
256 511
512 1023
1024 2047
2048 4095
4096 8191
8192 16383
16384 32767
32768 65535
65536 131071
131072 262143
262144 524287
524288 1048575
1048576 2097151
2097152 4194303
4194304 8388607
8388608 16777215
16777216 33554431
33554432 67108863
67108864 134217727
134217728 268435455
268435456 536870911
536870912 1073741823
1073741824 2147483647
图表:
答案 2 :(得分:2)
让我们尝试追踪它:
设N为8 。
1 + f(4)+ f(4)
=> 1 + 2 + f(2)+ f(2)+ f(2)+ f(2)
=> 1 + 6 + f(1)+ f(1)+ f(1)+ f(1)+ f(1)+ f(1)+ f(1)+ f(1)
当n = 8时; work = 15
设N为4 。
1 + f(2)+ f(2)
=> 1 + 2 + f(1)+ f(1)+ f(1)+ f(1)
当n = 4时; work = 7
设N为2
1 + f(1)+ f(1)
当n = 2时; work = 3;
设N为1
1
当n = 1时; work = 1
所以一眼就看出工作模式似乎 2n - 1
我们仍然需要证明它!
从算法中,递归关系是:
W(1)= 1
W(N)= 1 + 2 * W(N / 2)
通过归纳证明
基本案例:
W(1)= 2(1) - 1 = 1 根据需要。
递归案例:
假设W(N / 2)= 2(n / 2) - 1 = n - 1
W(N)= 1 + 2 *(N / 2)
应用归纳法......
W(N)= 1 + 2(n - 1)= 1 + 2n - 2 = 2n - 1 根据需要
因此,复杂性 O(2n - 1)因为 O是反身的
=> O(max {2n,-1})因总和规则
=>的 O(2N)强>
=>由于缩放规则
, O(n)答案 3 :(得分:0)
此代码与二进制树遍历,
非常相似void f( int N ){
sum ++;
if ( N > 1){
f( N /2); //like Traverse left subtree
f( N /2); //like Traverse right subtree
}
基本遍历每个节点一次,时间复杂度O(N)
。
n/8
n/4 ---------
n/8
n/2 ------------------
n/8
n/4 ---------
n/8
n -------------------------------
n/8
n/4 ---------
n/8
n/2 ----------------
n/8
n/4 ---------
n/8
这一直持续到传递的值变为1或0。