【剑指offer】快速幂 [Go语言]

237 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

题目

求快速幂

题解

Pow(x,n) 关于一道计算x的n次幂的问题,如果采用累乘的形式,那就是最朴素的,最简单的一种求解方式,但不实用,累乘的算法的时间复杂度是O(n)。但是我们可以使用快速幂算法降低时间复杂度,将时间复杂度降低到O(logn),其中n是幂。

快速幂:

快速幂的做法简单来说就是把原来的幂拆成多个2的x次幂相加,比如5的11次方就拆成5的(1+2+8)次方,其中(1+2+8)是 20+21+23,怎么得出这一串的呢?就是把11次幂写成二进制就是:1011,然后1011换算成十进制的过程就是上面那一串~

所以原来要累乘11次的结果现在只需要累乘3次,分别乘5的1次方、5的2次方、5的8次方,可能有人会困惑,那么5的8次方也要累乘啊!有啥区别,所以在计算的过程就有技巧了;

以Pow(x,n)为例:

  1. 先初始一个变量ans=1.0,然后用一个变量base保存x,然后根据n的二进制的位数,循环执行该位数次数的base *= base,并且不断将n向右移位1位,直到n=0,这么得下来,base将会是x2、x4、x8、x16……,然后在执行之前也要进行判断
  2. 如果 n&1!=0,也就是说n的最右边一位是1,那意味需要把base累乘进ans,如果是0,那就不做操作,继续 base *= base。

AC Code

func myPow(x float64, n int) float64 {
    if n == 0 || x == 1.0{
        return 1.0
    }
    var ans float64 = 1.0
    var base float64 = x
    b := n
    if n < 0{
        b *= -1
    }
    for b != 0{
        if b & 1 != 0{
            ans *= base
        }
        base *= base
        b >>= 1
    }
    if n < 0{
        return 1.0/ans
    }
    return ans
}