Pow(x, n)

这道题的直观思路不难,但是要注意很多细节问题。

首先,x要考虑整数、小数和0的情况。0不能取负数次方,0的0次方没有数学意义,可以取0也可以取1。

由于这里要处理x为小数的情况,因此x的类型为double,要判断一个double类型的x是否等于0,不能直接用(x==0.0),因为在计算机内表示小数时都有误差。

判断两个小数是否相等,只能判断它们的绝对值之差是否在一个很小的范围内。

其次,当n为负数是,要注意有一个取倒数的操作。

比较直观的解法如下:

class Solution {
public:
    bool equal(double x1, double x2)
    {
        if((x1-x2>-0.000001)&&(x1-x2<0.000001))
            return true;
        else
            return false;
    }
    
    double myPow(double x, int n) {
        double result=1;
        if(equal(x,0.0))
            return 0.0;
        if(n==0)
            return 1.0;
        else if(n>0)
        {
            for(int i=0;i<n;i++)
                result*=x;
        }
        else
        {
            for(int i=0;i<(-n);i++)
                result*=x;
            result=1/result;
        }
        return result;
    }
};

但是这种方法没有考虑时间复杂度,当n很大时,无法满足时间复杂度的要求。因此采用下面递归的方法,将求一个数的n次方转化为求一个数n/2次方再平方的问题:

class Solution {
public:
    bool equal(double x1, double x2)
    {
        if((x1-x2>-0.000001)&&(x1-x2<0.000001))
            return true;
        else
            return false;
    }
    
    double myPow(double x, int n) {
        double result=1;
        bool flag=false;
        if(equal(x,0.0))
            return 0.0;
        if(n==0)
            return 1.0;
        if(n==1)
            return x;
        if(n<0)
            flag=true;
        n=(n>0)?n:(-(++n));
        double half_result=myPow(x,n/2);
        result = half_result*half_result;
        if(n&1==1)
            result*=x;
        if(flag)
            result=1.0/(result*x);
        return result;
    }
};

当遇到测试用例x=2.0,n=INT_MIN时,(-n)的值就会溢出。因为INT_MAX为2147483647,但是INT_MIN为2147483648。因此在n为负数时,可以先将n-1,最后在计算result时再乘回来。

 

posted on 2016-05-16 11:13  summerkiki  阅读(234)  评论(0编辑  收藏  举报