剑指 Offer 16-数值的整数次方c++

------------------------------------二刷2020/12/24--------------------------------
确实掌握了快速幂,可喜可贺可喜可贺

//位运算快速幂
class Solution {
public:
    double myPow(double x, int n) {
        long Special = n;
        if(n < 0) return 1 / Pow(x, - Special);
        return Pow(x, n);
    }
    double Pow(double x, long n) {
        double temp = x ;
        double ans = 1;
        while(n) {
            if(n & 1) ans*=temp;
            temp*=temp;
            n >>= 1;
        }
        return ans;
    }
};
//二分法快速幂
class Solution {
public:
    double myPow(double x, int n) {
        long Special = n;
        if(Special < 0)
        return 1/Pow(x, -Special);
        return Pow(x,n);
    }
    double Pow(double x, long n)
    {
        if(n == 0) return 1;
        if(n == 1) return x;
        double temp = Pow(x, n / 2);
        if(n % 2 == 0) return temp * temp;
        return temp * temp * x;
    }
};

------------------------------------一刷-----------------------------------------------

题目描述

在这里插入图片描述

解法一 二分快速幂

定义临时变量temp,将递归的复杂度缩减到O(logN)

class Solution {
public:
    double myPow(double x, int n)
    {
        long jud=n;
        if (jud<0) {
            return 1/myPow(x,-jud);
        }
        return Pow(x,jud);
    }
private:
    double Pow(double x, long n)
    {
        if (n==0) return 1;
        if (n==1) return x;
        double half=Pow(x, n / 2);
        if (n%2==0)
            return half*half;
        else
             return half*half*x;
    }
};

这题有个坑,写的时候倒在最后几个测试用例好几次…
在这里插入图片描述
要考虑到int类型的整数的负数的最小值的绝对值是比最大值的绝对值大1的,这是组原里面的知识。
然而后面看到一个更厉害的递归…不知道作者是谁

class Solution {
public:
    double myPow(double x, int n)
    {
        if(n==0)
        return 1;
        if(n==1)
        return x;
         double temp=myPow(x,n/2);
         if(n%2==0)
         return temp*temp;//正偶数
         if(n>0)
         return temp*temp*x;//正奇数
         else
         return temp*temp/x;//负奇数
    }
       
};

解法二 位运算快速幂

将幂转化为二进制表示,再求出分解后各项总的乘积
比较懒,借用Krahets的解释
在这里插入图片描述
快速幂-百度百科

class Solution {
public:
    double myPow(double x, int n) {
        if(n == 0) return 1;
        if(n == 1) return x;
        long jud = n;
        double ans=1;
        if(n < 0)
        {
            x=1/x;
            jud=-jud;
        }
        while(jud)
        {
            if((jud & 1) == 1) ans *= x;//幂的二进制最低位为1说明此项为x^2(i-1)*1
            //if((jud & 1) == 0) ans*=1;//幂的二进制最低位为1说明此项为x^2(i-1)*0=1
            x *= x;//每项x的值都为前一项的平方
            jud >>= 1;//幂右移,进行下一位是1或者是0的判断
        }
        return ans;
    }
};

在这里插入图片描述
时间复杂度O(logN):n转化为2进制有几位就算几次
空间复杂度O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值