Pow(x,n)

来源:互联网 发布:电信网络诈骗例子 编辑:程序博客网 时间:2024/06/08 01:13

原题:

Implement pow(x, n).

应该是不调用Math.Pow()方法实现Math.Pow()。


思考过程:

让我想起以前做的用减法实现除法的方法。这次以乘法实现乘方为了不超时,乘数应该是以指数形式增长的。一开始想到了一个办法自觉得应该没问题,结果还是超时了:

public double myPowTLE(double x, int n) {        double ret = 1;        int absN = Math.abs(n);        while (absN > 0){            int i = 1;            double j = x;            while (i * 2 < absN){                j *= j;                i *= 2;            }            absN -= i;            ret *= j;        }        return (n > 0)? ret:(1 / ret);    }

思路大概是:比如n为31,依次求出x的2,4,8,16次方,然后从头来,再乘x的2,4,8次方,然后是2,4次方,然后是1次方。结果还是超时了。

看了别人的递归思想,比这个要优化,思路是:x ^ 31 = x * (x ^ 15) ^ 2,x ^ 15 = x * (x ^ 7) ^ 2,x ^ 7 = x * (x ^ 3) ^ 2......

解题思路请看代码注释。(此外还要处理n = Integer.Min_VALUE,n = 0的情况)


结果代码:

public double myPow(double x,int n) {        if (n == 0) return 1;        if (n == Integer.MIN_VALUE)            return (myPow(x, n + 1) / x);//如果是最小int,需要返回(-2147483647 / x),不可以返回(1 / myPow(x,2147483647))        int absN = Math.abs(n);//根据n是否为正决定最后返回结果        double ret = 0;        if (absN % 2 == 0) {//根据n是否可以整除2分两种情况递归            double half = myPow(x, absN >> 1);            ret = half * half;        } else {            double fakeHalf = myPow(x, (absN - 1) >> 1);            ret = fakeHalf * fakeHalf * x;        }        return (n > 0) ? ret : (1 / ret);    }


原创粉丝点击