例题:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0。
幂就是底数的乘积,如果直接暴力破解时间复杂度为O(N)
下面是两种优化算法
解法一:递归(时间复杂度O(NlogN))
- 原理:
求x^n:
如果n是偶数,则计算x^(n/2) * x^(n/2);
如果n是奇数,则计算x^(n/2) * x^(n/2) * x;
PS:如果幂为负数,则先将幂取绝对值,最后结果取其分数
例如:
x ^ 11 = x ^5 * x^5 * x
x ^5 = x^2 * x^2 * x
x^2 = x * x - 代码实现
public double Power(double base, int exponent) {
double ans = 0.0;
int e = exponent > 0 ? exponent:-exponent;
// >> 左移运算符,相当于除2
ans = Power(base, e >> 1);
//n无论奇偶都有这一步
ans *= ans;
//如果n为奇数,再乘以base
if((e & 1 )== 1){
ans *= base;
}
return exponent>0 ?ans:1/ans;
}
解法二:快速幂(时间复杂的O(logN))
- 原理:
快速幂就是快速算底数的n次幂,把exponent转换成二进制数
例如 exponent = 11 = 2^0 + 2^1 + 2^3 二进制为 1011
- 代码实现:
public double Power(double base, int exponent) {
double ans = 1;
int e = exponent >0 ? exponent : -exponent
while( e ! = 0){
if( e & 1 != 0 ){
ans = ans * base; // 二进制中为1 对应的幂值相乘
}
base = base * base; //求每次循环的单个幂值
e >>= 1; //按位右移
}
return exponent >0 ? ans : 1/ans;
}