分治之快速幂算法
Contents
快速幂算法
快速幂(Exponentiation by squaring,平方求幂)是一种简单而有效的小算法,它可以以**O(log N)**的时间复杂度计算乘方。快速幂不仅本身非常常见,而且后续很多算法也都会用到快速幂。
思考一个问题, 2的10次方,怎么做?
方法一:最朴素的做法,就是 2 * 2 = 4, 4 * 2 = 8, 8 * 2 = 16… 共进行了 9次乘法运算。
**方法二 ** : 快速幂算法
2 的10次方 = 2的5次方 * 2的5次方;
2的5次方 = 2的2次方 * 2的2次方 * 2
使用这种方式, 我们计算 2的10次方进行了 5 次乘法运算
一,快速幂 + 递归
快速幂算法的本质是分治算法。 举个例子, 如果要计算 x ^ 64
x→ x^2 → x^4 → x^8 → x^16 → x^32 → x^64
从x 开始,依次对上一次的结果进行平方运算, 我们只需要进行 6 次运算就可以得到 x ^ 64的值。
而不需要线性的计算63次
直接从左到右进行推导看上去很困难,因为在每一步中,我们不知道在将上一次的结果平方之后,还需不需要额外乘 x 但如果我们从右往左看,分治的思想就十分明显了:
- 当我们计算 x ^ n时,我们先计算 x ^ (n/2)
- 如果 n 为偶数, 则 x = x ^ (n/2) * x ^ (n/2)
- 如果 n 为奇数, 则 x = x ^ (n/2) * x ^ (n/2) * x
- 递归边界条件, n == 0, 任何数(除0以外) 的0次方都是1.
代码如下 :
|
|
复杂度分析 :
时间复杂度 : O(log N) 分治计算,每次计算均折半,复杂度 O(log N)
空间复杂度 : O(log N) 递归使用栈空间, O(log N)
二,快速幂 + 迭代
代码如下:
|
|
复杂度分析 :
时间复杂度 : O(log N) 每次均折半查找
空间复杂度 : O(1) 没有使用额外的内存空间
Author 飞熊
LastMod Jun 24