如何证明此算法为O(loglogn)
i <-- 2
while i < n
i <-- i*i
嗯,我相信我们应该先从n / 2^k < 1
开始,但这会产生O(logn)
。有什么想法吗?
我想以一种简单的方式看待这个,一次迭代后发生的事情,经过两次迭代后,以及经过k次迭代后,我想这样我将能够更好地理解如何正确计算。您如何看待这种方法?我是新手,请原谅。
答案 0 :(得分:0)
让我们对所提出的算法使用名称A
。让我们进一步假设输入变量为n
。
那么严格来说,A
不在运行时复杂度类O(log log n)
中。 A
必须位于(Omega)(n)
中,也就是说,就运行时复杂度而言,它至少是线性的。为什么?有i*i
,一个依赖于i
的乘法,它依赖于n
。天真的乘法方法可能需要二次运行时复杂性。更复杂的方法将减少指数,但就n
而言,不会降低线性。
为了完整起见,比较<
也是线性运算。
出于这个问题的目的,我们可以假设乘法和比较是在恒定时间内完成的。然后,我们可以提出一个问题:对于给定的>
,我们必须多久应用一次恒定时间操作*
和A
直到n
终止?
简单地说,乘法减少了对数的工作量,并且迭代应用导致对数的进一步减少。我们如何证明这一点?幸运的是,由于A
的简单结构,我们可以将A
转换为可以直接求解的方程。
A
将i
更改为2的幂,然后重复执行此操作。因此,A
计算2^(2^k)
。 2^(2^k) = n
什么时候?为了解决k
的问题,我们两次使用对数(以2为底),即忽略底数,得到k = log log n
。由于<
符号,可以忽略O
。
要回答原始问题的最后一部分,我们还可以查看每次迭代的示例。对于while循环的每次迭代,我们可以在while循环主体的末尾注意到i
的状态:
1: i = 4 = 2^2 = 2^(2^1)
2: i = 16 = 4*4 = (2^2)*(2^2) = 2^(2^2)
3: i = 256 = 16*16 = 4*4 = (2^2)*(2^2)*(2^2)*(2^2) = 2^(2^3)
4: i = 65536 = 256*256 = 16*16*16*16 = ... = 2^(2^4)
...
k: i = ... = 2^(2^k)