LeetCode 第 50 题 (Pow(x, n))
Implement pow(x, n).
这个题目非常简短,求
xn
。其中
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;
}
};
这个代码虽然从原理上是正确的,但是当
所以我们要想点其他的办法。
我们知道 xn1+n2=xn1×xn2 。如果 xn1 和 xn2 很容易算出来的话这样比直接算 xn1+n2 要快速。
而
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
的最高位还是
所以当
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;
}