所以我想知道以下问题的时间复杂性。正确的解决方案是它的O(logN);如果这个循环终止,我理解这一点。但是因为我们只有一半,所以理论上我可以真正接近0,但永远不会结束?!
int a = 0, i = N;
while (i > 0) {
a += i;
i /= 2;
}
答案 0 :(得分:1)
是的,循环实际上会结束。由于i
是int
,因此当您将i
减半时,您将执行整数除法。此除法的结果将向下舍入到最接近的整数。
例如:
int i=3;
int j= i/2;
// j really is 1.5, but we're performing integer division
// so the result will be j =1
如果我们考虑运行N=5
的程序,我们会:
第一次迭代:
i=5;
i = i/2 = 5/2 = 2.5 = 2; //Round 2.5 down
第二次迭代:
i=2
i = i/2 = 2/2 = 1;
第三次迭代:
i=1;
i = i/2 = 1/2 = 0.5 = 0; //Round 0.5 down, loop finishes
答案 1 :(得分:1)
重要的是要记住,您要划分int
,而不是浮点值,因此没有小数部分。相反,任何剩余部分都将被丢弃。因此,一旦你下降到1,其中一半是0.5,因为你只取整数部分,你将得到0.因此,这最终会完成。
例如,如果您从10
开始:
10 / 2
是5
5 / 2
为2
,余数为1
- 余数被丢弃 - i
为2
2 / 2
是1
1 / 2
为0
,余数为1
- 余数被丢弃 - i
为0
答案 2 :(得分:1)
由于您使用整数运算,我确实会转到0。 这是使用picoc
的交互式示例$ picoc -i
starting picoc v2.1
picoc> #include <stdio.h>
#include <stdio.h>
picoc> int a=0, i=10;
int a=0, i=10;
picoc> a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a=10 i=5
picoc> a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a=15 i=2
picoc> a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a=17 i=1
picoc> a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a += i; i /= 2; printf("a=%d i=%d\n",a,i);
a=18 i=0
此时你的循环已经终止。