我在SO问题中找到了以下for循环。
我发现时间复杂度为O(n log n)
。
如果我们将k *= 2
更改为k *= 3
,我将如何找到时间复杂度?
// 'int n' is defined somewhere
int var = 0;
for (int k = 1; k <= n; k *= 2)
for (int j = 1; j <= n; j++)
var++;
答案 0 :(得分:8)
时间复杂度仍为O(n log n)
。
对于k *= 2
,log
将为2。
对于k *= 3
,log
将为3。
但log
基数的变化只会影响结果的常数因子(这可以从logba
= logca / logcb
的事实中得出,对于任何基数{{1} }),在big-O表示法中被忽略,因此它们具有相同的时间复杂度。
我们从哪里获得c
?
嗯,log2n
的值如下:
k
当然上面只有1, 2, 4, 8, 16, ..., 2m for some m, where 2m <= n < 2m+1
= 20 + 21 + 22 + ... + 2m
(m+1
到0
)条款,因此循环运行m
次。
现在,如果我们可以使用一些基本对数来获得m+1
的{{1}}:
m
我们也可以按照与n
完全相同的方法,只需将2m = c.n for some constant c, where 1 <= c < 2
log22m = log2(c.n)
m log22 = log2(c.n)
m.1 = log2c + log2n
m = O(log2c + log2n)
= O(log2n) // constant terms can be ignored
替换为k *= 3
。
答案 1 :(得分:3)
答案是N×log 3 N。
要了解原因,您需要弄清楚为什么原始问题的答案是N×log 2 N.它会执行多少次(我们称之为k
)?它将根据需要执行多次,以使2
自身相乘,以使结果超过N
。换句话说,2 k &gt; N.现在将对数应用于表达式的两侧(可以找到对数的定义here)以查看k
&gt;登录<子> 2 子>Ñ
我们使用2
作为对数基数的原因是左边的指数的基数是2
。很容易看出,如果exponen的基数是3
,则应用log 3 可以得到你正在解决的问题的答案。
答案 2 :(得分:0)