LeetCode--Pow(x,n)

Problem50—Pow(x,n)

Disciption


Implement pow(x, n).

Trap


n的输入为int型,当n为MIN_INT时,取反之后会溢出

Solution


  • Brute
    暴力计算 xn
  • Binary
    二分法
  • Bit
    位操作法

Code

  • Code for Brute

//迭代版本
class Solution {
public:
    double myPow(double x, int n)
    {
    double ans = 1.0;
    bool flag = true;
    if(n < 0)
    {
        flag = false;
        ans = ans*x;
        n = -n-1;
    }
    while(n)
    {
        ans = ans*x;
        n--;
    }
    if(!flag)
        return 1.0/ans;
    return ans;
    } 
};
//递归版本
class Solution {
public:
    double myPow(double x, int n)  
    {  
        if(n==0)  
            return 1.0;  
        if(n<0)  
            return 1.0/(myPow(x,-n-1)*x); 
        return x*pow(x,n-1);  
    }  
};

显然暴力法求解的时间复杂度为 O(n) ,提交过去就直接RE了。

  • Code for Binary

采用二分法的思想,根据 xn=xn/2×xn/2×xn%2 (n可为奇数或偶数)这个递归公式,可以很容易写出代码,时间复杂度为 O(log(n))

//版本1
class Solution {
public:
        double myPow(double x, int n)
        {
            //终止条件
            if(n < 0)
                return 1.0/(myPow(x,-n-1)*x); //当n取值为INT_MIN时,直接取反可能会溢出
            if(n == 0)
                return 1.0;
            if(n == 1)
                return x;
            //递归
            double res = myPow(x,n/2);
            return res*res*myPow(x,n%2);
        }
};

代码十分简洁易懂,但这种算法将n为奇数和偶数的情况合并在一起,会引起无必要的递归出现,占用递归栈的空间。比如当n取值为65,用这种解法将会无谓地调用多次myPow(x,0)。基于这一点,我们可以将n分奇偶递归,代码如下。

//版本2
class Solution {
public:
        double myPow(double x, int n)
        {
            double res = 1.0;
            //终止条件
            if(n < 0)
                return 1.0/(myPow(x,-n-1)*x); //当n取值为INT_MIN时,直接取反可能会溢出
            if(n == 0)
                return 1.0;
            //递归
            if(n%2 == 1)
            {
                res = myPow(x,n/2);
                return res*res*x;
            }
            else
            {
                res = myPow(x,n/2);
                return res*res;
            }
        }   
};
  • Code for Bit

最后一种解法比较巧妙,考虑n为129,写成二进制的形式为10000001, x10000001 等价于 x8×x1 ,当n的二进制位上为0时,实际上只是乘以1。所以我们只需要对n进行右移操作,然后判断n的最低位是否为1,代码如下。

class Solution {  
public:  
    double myPow(double x, int n) 
    {    
        if(n < 0)  
            return 1.0/(pow(x,-n-1)*x);  
        if(n == 0)  
            return 1.0;  
        double res = 1.0 ;  
        //循环移位
        for(;n > 0; x *= x, n>>=1)  
        {  
            if(n&1 == 1) //判断n的最低位是否为1
                res *= x;  
        }  
        return res;  
    }  
};  

Tips


  1. C++中需要采用精确的除法时,只需要保证除数和被除数中有一个为浮点数即可。
  2. 使用递归算法时,一定要注意列出递归表达式和终止条件。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值