寻找倍数的时间复杂度分析

Posted dalt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻找倍数的时间复杂度分析相关的知识,希望对你有一定的参考价值。

  经常能遇到类似于这样的情况,给出一个n,寻找[1,n]中每个数x的所有落于[1,n]中的倍数。

  举一个比较常见的例子,我们用普通的筛法寻找[1,n]之间的所有素数并标记。代码大概如下:

isPrime = new int[n + 1]
for(i = 1; i <= n; i++)
    isPrime[i] = true
isPrime[1] = false
for(i = 2; i <= n; i = i + 1)
    for(j = i + i; j <= n; j = i + i)
         isPrime[j] = false

  很容易发现对于数x,在区间[1,n]中其倍数数目为floor(n/x)。而累加每个数,倍数的总数为$ \sum_{i=1}^n{\lfloor\frac{n}{i}\rfloor} $。很容易发现这个值的既是我们上面程序的时间复杂度,那么这个值大约是多少呢?

  很容易发现这个值的一个上界$ n\sum_{i=1}^n{\frac{1}{i}} $,之后我们把视角移动到新的上界上来。注意到下面不等式的成立(想起黎曼积分的定义):

$$ \int_i^{i+1}{\frac{1}{x}dx}\le\frac{1}{i}\le\int_{i-1}^i{\frac{1}{x}dx} $$

进行累加可以得到:

$$ \int_1^{n+1}{\frac{1}{x}dx}\le\sum_{i=1}^n{\frac{1}{i}}\le 1+\int_1^n{\frac{1}{x}dx}\Rightarrow\ln\left(n+1\right)\le\sum_{i=1}^n{\frac{1}{i}}\le 1+\ln n $$

因此上面程序的时间复杂度就可以表示为O(nln(n)),是一个相当不赖的时间复杂度。当然还有许多可以优化的空间,甚至还可以优化为线性的欧拉筛。

以上是关于寻找倍数的时间复杂度分析的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《二分枚举》简单04 —— LeetCode 1346. 检查整数及其两倍数是否存在

关于代码片段的时间复杂度

以下代码片段的时间复杂度是多少?

显示范围内给定数字的倍数

显示范围内给定数字的倍数

以下代码片段的算法复杂度