LeetCode 第 50 题 (Pow(x, n))

来源:互联网 发布:c语言四大圣经先后顺序 编辑:程序博客网 时间:2024/06/06 18:22

LeetCode 第 50 题 (Pow(x, n))

Implement pow(x, n).

这个题目非常简短,求 xn。其中n 为整数。
最简单的想法就是用一个循环,将 x 自乘n 次。按照这个思路有下面的代码。

class Solution {public:    double myPow(double x, int n)     {        int sign = 1;        if(n < 0)        {            n = -n;            sign = -1;        }        double ret = 1;        for(int i = 0; i < n; i++)        {            ret = ret * x;        }        if(sign == -1)        {            ret = 1 / ret;        }        return ret;    }};

这个代码虽然从原理上是正确的,但是当n 比较大时运行速度实在是太慢。这样提交的话肯定会运行超时。
所以我们要想点其他的办法。

我们知道 xn1+n2=xn1×xn2 。如果 xn1xn2 很容易算出来的话这样比直接算xn1+n2 要快速。


n=i=031ci×2i

x2, x4, x16 这样的数字很容易计算的。所以我们可以利用这个特点来加快计算。下面是代码:

double myPow(double x, int n) {    double table[32];    int sign;    table[0] = x;    for(int i = 1; i < 32; i++)    {        table[i] = table[i - 1] * table[i - 1];    }    if(n < 0)    {        n = -n;        sign = -1;    }    double ret = 1;    int i = 0;    while(n)    {        if(n & 1) ret = ret * table[i];        n = (unsigned int)n >> 1;        i ++;    }    if(sign == -1)    {        ret = 1 / ret;    }    return ret;}

这个代码还有一处需要特别解释解释。

n = (unsigned int)n >> 1;

为什么这里要加上 “(unsigned int)”? 只是为了应对一个特殊条件,就是 n=2147483648,这个数是最小的 int 型变量(INT_MIN),n 不在 int 型变量所能表示的数字范围内,n=2147483648

对于负数,n=n>>1 之后 n 的最高位还是 1
所以当 n=2147483648 时,下面这个循环是死循环。

while(n){    n = n >> 1;}

所以这里要将 n 转换为 unsigned int 类型。

上面的代码还可以再优化一点。我们可以原地计算上面代码中用到的那个 Table。下面是代码。

double myPow(double x, int n) {    int sign;    if(n < 0)    {        n = -n;        sign = -1;    }    double ret = 1;    while(n)    {        if(n & 1) ret = ret * x;        x = x * x;        n = (unsigned int)n >> 1;    }    if(sign == -1)    {        ret = 1 / ret;    }    return ret;}
1 0
原创粉丝点击