剑指offer之数值的整数次方C++解法

剑指offer之数值的整数次方C++解法

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

快速幂
求ab, 朴素算法即a连乘b次的时间复杂度是O(b)也就是O(n),快速幂能做到O(logn),原理如下:
把b拆成二进制,该二进制数第i位的权为2i-1,例如当b==11时,其二进制是1011,a11=a ^ (20+21+23)=a1*a2*a8, 因此原来算11次,现在只需要算3次。这三项可利用位运算进行快速计算。
位运算常用于:1.二进制取位操作:number&1即取number二进制的最末位。2. 判断奇偶:number&1 ==0为偶,number&1 ==1为奇。

class Solution {
public:
    double Power(double base, int exponent) {
        int p = abs(exponent);
        double ans = 1.0; //注意ans的数据类型
        while(p){
            if(p&1)
                ans *= base;
            base*=base;
            p>>=1;
        }
        return exponent<0? 1/ans:ans; //若exponent为负数,则结果应是exponent为正数的结果的倒数
    }
};

对二进制指数exponent,每次向右移动一位检查末尾是否为1,若为1,则ans更新为ans乘以当前的base,exponent二进制数中每一位都对应着一个base,不断的让base*=base目的即是累乘,以便随时对ans做出贡献。
例如

  1. 当exponent为1时,二进制只有一个1,这时ans为初始值1.0,base为原始base,即ans=ans*base=1.0 *base=base,然后base累乘一次为base2,exponent右移一位后为0,结束循环,此时ans==base;
  2. 当exponent为2是,二进制为10,当前末位不满足if条件,因此base先自乘一次变为base2,然后右移一位满足if条件,此时ans为初始值1.0,base为base2,ans=1.0*base2=base2

也就是说,对于指数b,假设其二进制有n位(不包括开头的0):
第n位对应着a1
n-1位对应着a2
n-2位对应着a4
……
当第i位为1时,将其对应的a2^(n-i)与上一步的乘积累乘,循环至exponent为0结束,返回结果。

你可能感兴趣的:(剑指offer之数值的整数次方C++解法)