如何确定此编码段的时间复杂度?我是python的新手,非常感谢任何帮助!
sum = 0
i = n
while (i>= 1):
sum += i
i /= 2
i = n
j = 2
while (i >= 1):
sum +=i
i /= j
j *= 2
我认为第一个循环可能是(log n + 2)而第二个循环可能是(2log n + 4)但是我不确定我是否接近正确的轨道... < / p>
答案 0 :(得分:1)
就计算复杂性而言,O(n)是指实际的位长(它们称为位长)。
因此,每当 i 在第一个循环中运行时, i / = 2 会移位一位。在第二个循环中, i / = j 会移动1,2,4,8 ...位。
请记住,您有一个名为 n 的变量,而我所谈到的 n (输入的位长)实际上是关于CC理论的惯例。
因此,假设您使用仅使用变量重命名编写的脚本: n 到 m 。
sum = 0
i = m
while (i>= 1):
sum += i
i /= 2
i = m
j = 2
while (i >= 1):
sum +=i
i /= j
j *= 2
我刚刚重命名了变量。
现在让我们总结:
第一个循环具有“逐位”复杂性,因此符号为O(n)(线性复杂度,每次迭代一位)。
编辑:第二循环具有如下复杂性:“在Kth循环中,它将消耗1 + 2 + ... + 2 ^(k- 1)位:它将消耗2 ^ K - 1位“。
因此,如果Kth循环消耗该位数,我们说:K ^迭代2 ^ K位。我们说“对数”:O(log2(n))。
最终结果是:O(log2(n))+ O(n),其具有线性顺序,因为n> 1。 LOG(n)中。
答案 1 :(得分:0)
这是我的答案。为了更加数学精确,你可能应该像我一样写出不等式而不是等式,但无论如何总体推理都不会改变。 如果有意义或发现错误,请通过评论告诉我。
第一个循环的迭代时间与将i降低到小于1的时间相同。
它的时间复杂度为O(log_2(n+1))
,其中log_2表示基于2的对数。
0 i = n
1 i = n / 2
2 i = n / 2 / 2
k i = n/ 2^k
你问自己:k是什么样的n = 2^k
?
k = log_2(n)
当然,你不会被var sum分心,因为变量不会干扰驱动循环的那个。
第二个循环也是由i除以2的倍数驱动的,但是在每次迭代时通过乘以j * 2
来加速。其时间复杂度为log_2(n + 1)/ 2。
1 i = n / 2 j = 2
2 i = n / 2 / 2 / 2 j = 4
3 i = n / 2 / 2 / 2 / 2 / 2 / 2 j = 8
k i = n / 2^(k) * 2^(k) j = 2^k
k i = n / 2^(2k) j = 2^k
每次迭代k, j = 2^k
。
迭代k+1
,j = 2^(k+1)
。
迭代k+1
:i /= 2^(k+1)
什么是k,n = 2^(2k)
?
2k = log_2(n)
k = log_2(n)/2
log_2(n)/2
log_2(sqrt(n))
两个循环没有嵌套,我在它们之间重置为n,所以它们只是总结。
log_2(n+1) + log_2(sqrt(n+1))
log_2(n+1 + sqrt(n+1))