这个计算 a^n 的算法是如何被重写以在 O(log n) 时间内运行的?
Posted
技术标签:
【中文标题】这个计算 a^n 的算法是如何被重写以在 O(log n) 时间内运行的?【英文标题】:How did this algorithm for computing a^n get rewritten to run in O(log n) time? 【发布时间】:2013-10-07 06:15:02 【问题描述】:假设你想计算一个n。一个简单的算法会将a、n乘以如下:
result = 1;
for(int i =1; i <= n; i++)
result *= a;
该算法需要 O(n) 时间。不失一般性,假设n=2^k
您可以使用以下方案改进算法:
result = a;
for (int i = 1; i <= k; i++)
result = result * result;
该算法需要 O(log n) 时间。对于任意的n,可以修改算法,证明复杂度还是O(logn)
好糊涂,那n=2k怎么算,为什么第二个例子中只显示了k?不明白这如何转化为 O(logn) 时间复杂度...
【问题讨论】:
拜托,您能否在一开始就说明该算法试图解决的问题是什么?这听起来很像家庭作业…… 这可能有助于理解您正在考虑一种特殊情况,其中 n 是 2 的幂。在这种特殊情况下,您可以更有效地实施例程。 @nyarlathotep 不是家庭作业,而是教科书中的一个例子,没有解释为什么会这样。 不失一般性,假设 n=2^k。 这是很多失一般性。 【参考方案1】:第二种算法在一般情况下不起作用;它仅在存在一些 k 以便您可以编写 n = 2k 时才有效。如果有 k 可以做到这一点,那么通过取等式两边的对数,你会得到 log2 n = k。因此:
循环计数为 k,运行 O(log n) 次。 因此,循环运行时间为 O(log n)。如果你想摆脱神秘的k,你可以写
int result = a;
for (int i = 0; i < log2(n); i++)
result = result * result;
这更清楚地在 O(log n) 时间内运行,因为循环运行 log2 n 次,并且每次迭代都运行 O(1)。
我认为“不失一般性”说 n 是 2 的完美幂是不公平的,因为并非所有数字都是!上面的代码只有在 n 是 2 的幂时才有效。您可以使用 repeated squaring algorithm 将其推广到非二次幂,它具有 O(log n) 复杂度但适用于任何幂。
希望这会有所帮助!
【讨论】:
@templatetyedef 很棒的答案!谢谢你这么清楚!!我不知道为什么教科书对初学者来说不能更明确一点!再次感谢!以上是关于这个计算 a^n 的算法是如何被重写以在 O(log n) 时间内运行的?的主要内容,如果未能解决你的问题,请参考以下文章