本题有两个地方需要考虑。
1.正负号
题目的n取值范围为
−
2
31
-2^{31}
−231到
2
31
2^{31}
231。
如果n取
−
2
31
-2^{31}
−231,直接取该值负号,会出现内存溢出现象。
所以我们可以定义一个long类型再取负号,或使用abs函数。
2.暴力法超时问题
很多小伙伴会先想到逐个逐个乘,但这样在数值大的时候会超时。、
针对这个问题,我们可能尽可能增大基底x,减小幂次n。
比如2的10次方,可以写成4的5次方,还可以写成416^2,最后写成4256。
n为偶数:
x
n
=
(
x
2
)
n
/
2
x^n = (x^2)^{n/2}
xn=(x2)n/2
n为奇数:
x
n
=
x
∗
(
x
2
)
n
/
2
x^n = x*(x^2)^{n/2}
xn=x∗(x2)n/2
可以看到奇数时,就是比偶数的式子多乘了一个x,于是编程的时候就可以先判断是否是奇数,是奇数先乘下来。
依靠上面两式,迭代至n为0即可,也即最大化基底。
另外就是还有一些特殊情况,比如n=-0,x=+1等。
class Solution {
public:
double myPow(double x, int n) {
long k = abs(n);
double res = 1;
if(n == 0 || x == 1)
return 1;
cout << "test " << k << endl;
while(k!=0)
{
if(k%2 == 1)
{
res*= x;
}
x *=x;
k/=2;
}
return n>0?res : 1/res;
}
};