这个问题毫无疑问应该用快速幂来做,不过问题在于考虑各种临界情况,比如
- 底数为0的情况,这里默认全部返回0
- 指数为负数的情况
- 指数太大越界情况,这里题目不要求考虑
- 指数处于临界值的情况。这是个大坑,如 n = − 2147483648 n=-2147483648 n=−2147483648
Java 代码中
int32
变量 n ∈ [ − 2147483648 , 2147483647 ] n \in [-2147483648, 2147483647] n∈[−2147483648,2147483647],因此当 n = − 2147483648 n = -2147483648 n=−2147483648 时执行 n = − n n = -n n=−n 会因越界而赋值出错。解决方法是先将n存入long
变量 b b b,后面用 b b b 操作即可。来自大佬题解
算法复杂度
- 时间复杂度: O ( log n ) O(\log n) O(logn),循环的次数为 log 2 n \log_{2}n log2n
- 空间复杂度: O ( 1 ) O(1) O(1),使用的变量所占空间为常数。
class Solution {
public double myPow(double x, int n) {
//底数为0,由于浮点数不能判断==0,只有范围
if(Math.abs(x) < 1e-6){
return 0.0;
}
long exp = n;
if(exp < 0){
x = 1 / x;
exp = -exp;
}
double res = 1.0;
for(; exp > 0; exp >>= 1){
// 这种位运算一定要打括号
if((exp & 1) == 1)
res = res * x;
x = x * x;
}
return res;
}
}
当然了,这里也可以用递归的写法来做。如下所示
class Solution {
public:
double myPow(double base, int exponent) {
if(base == 0 && exponent <= 0)
return 0;
if(exponent < 0)
return 1.0 / PowerWithUnsighedExponent(base,abs(exponent));
else
return PowerWithUnsighedExponent(base, exponent);
}
double PowerWithUnsighedExponent(double base, int exponent){
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = PowerWithUnsighedExponent(base, exponent >> 1);
//用移位运算代替除法运算
result *= result;
if(exponent & 0x1 == 1)
result *= base;
//用与运算代替求余运算
return result;
}
};
算法复杂度
- 时间复杂度: O ( log n ) O(\log n) O(logn),开栈的深度为 log 2 n \log_{2}n log2n,每个栈计算时间为常数
- 空间复杂度: O ( log n ) O(\log n) O(logn),使用的变量所占空间为常数。