确定以下编码段的时间复杂度

时间:2014-02-17 22:40:20

标签: python time-complexity

如何确定此编码段的时间复杂度?我是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>

2 个答案:

答案 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)

这是我的答案。为了更加数学精确,你可能应该像我一样写出不等式而不是等式,但无论如何总体推理都不会改变。 如果有意义或发现错误,请通过评论告诉我。

First Loop

第一个循环的迭代时间与将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+1j = 2^(k+1)

迭代k+1i /= 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))