我对软件工程课程的介绍刚刚达到时间复杂度并学习如何分析某些算法。我很难看到他们如何得到他们的解决方案并且希望有人可以解释它,希望有一些合乎逻辑的证据?
void foo(int N) {
int k = 1;
while (k < N * N) {
k = k * 2;
}
}
他们的解决方案是这个函数的Big-O是 O(logN) [我明白这里的日志是基数2]
我试图通过考虑将随机值分配给N来迭代多少次来解决这个问题而我找不到模式,任何帮助?
答案 0 :(得分:2)
k
每次增加2
因子的事实是算法logN
的原因。实际上,它是log(N^2)
,但是使用对数属性我们可以将其简化为2log(N)
,然后通过取{} {}}接近无穷大来获取2
N
来获取log(N)
1}}。
因此,时间复杂度为O(logN)
。
编辑:此外,可以看出k
从1
开始,当k
大于或等于N * N
时,程序结束。如果我们采用log(N^2)
,我们将知道程序将运行多少次迭代。通过这样做,我们还可以通过取k
的上限来确定log(N^2)
的结束值。
编辑:示例为N = 10
:N
的平方为100
。因此,k
会增加,直到2的幂高于或等于100
,即128
。
答案 1 :(得分:2)
使用你的高中代数。在p
次迭代后,k
的值为2^p
。 (这很容易检查。)循环将在k >= N^2
时停止执行。替换,循环停止
2^p >= N^2
现在解决:
log_2(2^p) >= log(N^2)
p >= 2 log(N)
因此循环将在非常接近2 log(N)
次迭代时停止。这是O(log(N))。
只有在操作数大小有固定限制的情况下,你才可以指出乘法是恒定时间,从而让你的老师去完成任务。没有这样的限制,问题也取决于乘法的渐近行为。
顺便说一下,O(log N)对于所有对数的基数是相同的。基数仅通过常数因子更改日志的值,而big-O忽略常量因子。