非递归循环快速幂

刷题过程中遇到一个快速求幂的方法,特此记录

分治思想:

        比如我们要计算x的y次方,通常情况我们需要执行y次。但是如果我们将其转化为(x*x) ^ (y/2)就只需要执行一半的时间了,那么如果是(x*x) * (x*x)) ^ (y/2/2)就只用四分之一的时间了,好。但这里有一个问题,你怎么知道y能一直被二整除呢?如果不能被整除怎么办?举个大家都会举的例子,计算3 ^ 10,第一次转化为了9 ^ 5 但下一次5/2不够除该怎么办?转化为(9^4)*(9^1),以下是递归写法。

def quick_pow(x, y):
    if y == 0:
        return 1
    ret = quick_pow(x, y // 2)
    return ret * ret if y % 2 == 0 else ret * ret * x

递归快速取模的算法思想没有问题,但是在递归的过程中,会使用很多额外的栈空间,是否存在一种办法,能通过迭代的循环方式完成,而非递归实现呢?答案当然是有的。我们只需要判断什么时候指数不能被2整除,则单独乘以底数,否则就将当前的数值平方即可。那么如何判断当前的指数是否能被2整除呢?

思路很简单:当一个数 & 1若为1,即该数的最后一位为1,不能被2整除,否则代表可以被2整数。


   10:     00001010
    1 :     00000001
按位与  00000000
------------------------
    9:      00001001
    1:      00000001

按位与  00000000


代码如下:

def quick_pow(x, y):
    res = 1
    while y:
        if y & 1:
            res *= x
        x *= x
        y = y >> 1
    return res

虽然算法不难理解 但是比较精妙!新技能get!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值