快速幂算法相关题目(Leetcode题解-Python语言)

50. Pow(x, n)

快速幂算法的目的,就是快速计算 x 的 n 次方。基本思路是把 n 视作二进制数,则 n 可以被分解为多个 2 的幂次方之和,如 12 对应 1100 等于 0 ∗ 2 0 + 0 ∗ 2 1 + 1 ∗ 2 2 + 1 ∗ 2 3 0*{2^0} + 0*{2^1} + 1*{2^2} + 1*{2^3} 020+021+122+123,即二进制数中每一位的0或1对应的正是系数。因此, x 12 = x 0 ∗ 2 0 + x 0 ∗ 2 1 + x 1 ∗ 2 2 + x 1 ∗ 2 3 {x^{12}} = {x^{0*{2^0}}} + {x^{0*{2^1}}} + {x^{1*{2^2}}} + {x^{1*{2^3}}} x12=x020+x021+x122+x123。从 n 的二进制形式可以得到系数,而对应的 x 的二次幂可以通过 x 自乘得到( x = x 2 0 , x ∗ x = x 2 1 , x 2 ∗ x 2 = x 2 2 . . . . . . x = {x^{{2^0}}},x*x = {x^{{2^1}}},{x^2}*{x^2} = {x^{{2^2}}}...... x=x20,xx=x21,x2x2=x22......)。实现上可以使用递归或者迭代,迭代的空间复杂度更优:

递归法:

class Solution:
    def myPow(self, x: float, n: int) -> float:
        def quickMul(N: int):
            if N == 0:
                return 1.0
            y = quickMul(N // 2)
            return y * y if N % 2 == 0 else y * y * x
        return quickMul(n) if n >= 0 else 1.0 / quickMul(-n)

迭代法:

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if x == 0.0: 
            return 0.0
        ans = 1
        if n < 0: 
            x = 1 / x
            n = -n
        while n:
            if n & 1: 
                ans *= x
            x *= x
            n >>= 1
        return ans

372. 超级次方

做这题需要知道的公式是: ( a ∗ b ) % M O D = ( ( a % M O D ) ∗ ( b % M O D ) ) % M O D (a*b)\% MOD = ((a\% MOD)*(b\% MOD))\% MOD (ab)%MOD=((a%MOD)(b%MOD))%MOD

class Solution:
    # 快速幂算法
    def quick_mul(self, x: int, n: int) -> int:
        MOD = 1337
        ans = 1
        while n:
            if n & 1:
                ans = ans * x % MOD
            x = x * x % MOD
            n >>= 1
        return ans

    def superPow(self, a: int, b: List[int]) -> int:
        MOD = 1337
        ans = 1
        x = a % MOD
        for y in b[::-1]:
            ans = ans * self.quick_mul(x, y) % MOD
            x = self.quick_mul(x, 10)
        return ans

关键是两点:一是根据公式,增加了多次取模操作(MOD);二是由于指数存储在了数组中,从右到左遍历是低位到高位,两种方法,一是用一个变量记录当前是第几位,则从数组取出来的数与 10 的多少次方相乘,二是每次将底数 x 乘以 10 次方,这样也相当于指数乘以 10,例如 x 123 = ( x 1 ) 3 + ( x 10 ) 2 + ( x 100 ) 1 {x^{123}} = {({x^1})^3} + {({x^{10}})^2} + {({x^{100}})^1} x123=(x1)3+(x10)2+(x100)1

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值