为啥代码的时间复杂度为 O(log n)?

Posted

技术标签:

【中文标题】为啥代码的时间复杂度为 O(log n)?【英文标题】:Why is Time complexity of the code O(log n)?为什么代码的时间复杂度为 O(log n)? 【发布时间】:2018-03-19 04:12:48 【问题描述】:

这是 Gayle Laakmann 在“Cracking the Coding Interview”一书中给出的代码。这里找代码的时间复杂度:-

int sumDigits(int n)
 int sum=0;
 while(n >0)

    sum+=n%10;
    n/=10

return sum ;

我知道时间复杂度应该是n的位数。

根据本书,它的运行时间复杂度是 O(log n)。书提供了简要说明,但我不明白。

【问题讨论】:

n 的位数为 log n。 (或者足够接近 O 复杂度的近似值。) n 不减 1,因此不是线性的。循环中的每一次通过,n 都会减少一个数量级 Code complexity的可能重复 【参考方案1】:
while(n > 0)

    sum += n % 10;
    n /= 10;

那么,这个 while 循环需要多少步才能使 n 变为 0?你在每一步中所做的,你将n10 分开。所以,你需要这样做k 次才能来到0。注意,k 是n 的位数。

让我们一步一步来: 第一步是当n > 0 时,你将n 除以10。如果n 仍然是正数,则将其除以10。你得到的是n/10/10n / (10^2)。第三次之后,它的n / (10^3)。在k次之后,它的n/(10^k) = 0。循环将结束。但这不是数学意义上的0,而是0,因为我们处理的是整数。你真正拥有的是|n|/(10^k) < 1,其中k∈N

所以,我们现在有了这个:

n/(10^k) < 1
n < 10^k
logn < k

顺便说一句。它也是n/(10^(k-1)) &gt; 1,所以它:

k-1 &lt; logn &lt; k。 (顺便说一句。别忘了,这是基础10)。

所以,您需要执行logn + 1 步骤才能完成循环,这就是为什么它是O(log(n))

【讨论】:

感谢 Adnan 的完美回答。【参考方案2】:

逻辑运行的次数是 log(n) 以 10 为底,这与 (log(n) 以 2 为底)/(log (10) 以 2 为底) 相同。就时间复杂度而言,这将只是 O(log (n))。请注意,以 10 为底的 log(n) 是表示 n 中位数的方式。

【讨论】:

以上是关于为啥代码的时间复杂度为 O(log n)?的主要内容,如果未能解决你的问题,请参考以下文章

预期时间复杂度为 O(n^2),但结果为 O(n)。有人可以解释为啥吗?

为啥快速排序算法的时间复杂度是O(nlogn)而不是O(n²)?

算法复杂度O(logn)详解

为啥基数排序的空间复杂度为 O(k + n)?

如何计算时间复杂度为 O(n log n) 的 XOR(二元)卷积

在o(N log N)时间内使用恒定的空间复杂度对链表进行排序