美文网首页算法
快速幂算法

快速幂算法

作者: 渔父歌 | 来源:发表于2020-06-21 10:17 被阅读0次

求解一个数的 n次方,我们一般直接累乘 n次,就像下面的代码一样:

def pow(x, n):
    result = 1
    for i in range(n):
        result *= x
    return result

但是这种方法只能用于指数 n比较小的情况,如果指数 n非常大的话,这种方法就不再适用了。

遇到这种情况下快速幂算法能够很好的解决我们的需求。

递归实现

观察 x^10 = x^5 * x^5
而 x^5 = x^4 * x
而 x^4 = x^2 * x^2
而 x^2 = x * x
即:x->x2->x5->x^10
根据上面的观察我们可以发现,下一步的结果总是上一步的平方或者上一步的平方再乘 x。

这样我们可以按照下面的规则从右边向左边计算:

  1. 计算 x^[n/2]。
  2. 如果 n是偶数,直接返回,否则乘上 x再返回。
  3. 如果 n=1,返回 x。

我们可以用递归来实现这个算法:

import math

def pow(x, n):
    if n == 1:
        return x
    
    r = pow(x, math.floor(n/2))
    return r*r if n%2 == 0 else r*r*x

迭代实现

任意一个正整数都可以用二进制来表示,比如:7 = 111(2) = 2^2 + 2^1 + 2^0
所以:x^7 = x ^ (2^2 + 2^1 + 2^0) = x^4 * x^2 * x
我们可以发现前一个式子总是后一个式子的 2n次方。

所以我们只要计算 x, x^2, x^4, x^8, ... , x^(2^n) ,然后根据 n的二进制表示来判断对应位是否带入计算,如果第 n位为 1,则结果乘上 x^(2^n),然后计算 x^(2^(n+1)),否则只计算 x^(2^(n+1))。

代码如下:

def pow(x, n):
    target = x
    result = 1
    while n > 0:
        if (n & 1) == 1:
            result *= target
        n = n >> 1
        target *= target
    return result

如果考虑 n为负数的情况,只需要在前面添加判断即可。
如果 n为负数,则 x = 1/x, n=-n。

相关文章

  • 模板 | 整数快速幂 & 快速幂取模

    快速幂: 所谓的快速幂,其目的是为了快速求幂,将时间复杂度从朴素算法的降到。 假如现在要求 ,按照朴素算法,就是将...

  • WOJ-315-高级机密

    主要参考了这篇文章:快速幂 蒙格马利算法 蒙哥马利(Montgomery)幂模运算是快速计算a^b%k的一种算法,...

  • 2018-07-09-快速幂

    参考:算法学习 - 快速幂和矩阵快速幂(复杂度Olog(n))C++实现 - CSDN博客

  • 快速幂算法

    快速幂算法,可以将时间复杂度从O(N)降为O(log2N)。 比如要算2^n (n>0),最简单的方法是: 时间复...

  • 快速幂算法

    原理 例子 计算。可以看到,原本需要12次乘法的计算,现在只需要5次乘法了。 分析 将的上标全写为二进制 可以看到...

  • 快速幂算法

    求解一个数的 n次方,我们一般直接累乘 n次,就像下面的代码一样: 但是这种方法只能用于指数 n比较小的情况,如果...

  • 快速幂

    快速幂 如果要我们求解,正常的做法往往是的算法,当数字很大的时候会耗费较多的时间,现在我们采用快速幂,可以将时间复...

  • Java 算法-快速幂

      说实话,自己是第一次接触到快速幂这种东西,觉得有必要记录下来。 题意: 样例: 挑战: 1.解题思路   在介...

  • Leetcode【372、1131】

    问题描述:【Math】372. Super Pow 解题思路: 快速幂算法。计算 a^b mod 1337,a 是...

  • (矩阵)快速幂

    快速乘法: 快速幂: 矩阵快速幂:

网友评论

    本文标题:快速幂算法

    本文链接:https://www.haomeiwen.com/subject/oteoxktx.html