我想计算这个嵌套for循环的复杂性:
s = 0;
for(i=1; i<=n; i*=2)
for(j=1; j<=i; j*=2)
s++;
我使用什么策略来找到这段代码的Big O复杂性?
答案 0 :(得分:3)
外部循环遍历1,2,4,8 ...... n ,这需要O(lg n )步骤,因为你只能加倍一个O (lg n )次,直到你点击 n 。
内循环也是如此。它只能到达 i ,但在外部循环的最后一次迭代中, i 达到其最大值,即 n ,因此也是O(lg n )。
将它们放在一起得到O((lg n )²)的上限,通常缩写为O(lg² n )。
答案 1 :(得分:2)
自行获得答案的策略
将n的不同值插入等式中,并绘制循环最内部运行次数的图表:
s = 0;
for(i=1; i<=n; i*=2)
for(j=1; j<=i; j*=2)
s++;
这样的事情:
n num_times_inner_loop_part_runs
1 1
2 3
3 3
4 6
5 6
6 6
7 6
8 10
9 10
...
15 10
16 15
...
31 15
32 21
您可以使用以下程序获取这些数据点:
int n = 9; //change this n
int counter = 0;
for(i=1; i<=n; i*=2){
for(j=1; j<=i; j*=2){
s++;
counter++;
}
}
cout << "counter is: " << counter << endl;
在{/ 1}} X / Y坐标平面上绘制,你会看到一条曲线。
命名最接近的曲线。在这种情况下,它是num_times_inner_loop_part
如果您绘制数据和X = (log(Y)^2)
,您会发现它们应该相互重叠。
因此,此函数的复杂性为X = (log(Y)^2)
,这是对O((log(n))^2)
的改进
答案 2 :(得分:1)
这段代码的时间分析:
答案 3 :(得分:0)