题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
拿到题目第一个想法当然是直接乘了,但是有时间的限制,所以我的想法就是用空间换时间,用递归的方法,将每一次计算的结果记录在数组中,避免重复计算,从而节省时间。
public class Solution {
boolean isPositive = true;//是否为正数
double[] array;
public double Power(double base, int exponent) {
//初始化
if(array == null){
if(exponent<0){
isPositive = false;
exponent = -exponent;
}
array = new double[exponent];
}
if(exponent == 0) return 1;
if(exponent == 1) return base;
if(array[exponent-1] != 0) return array[exponent-1];
array[exponent-1] = Power(base, exponent/2) * Power(base, exponent/2 + exponent%2);
//若指数为负,则取其倒数
if(exponent == array.length && !isPositive){
return 1/array[exponent-1];
}
return array[exponent-1];
}
}
除此之外,还有一种更简洁的方法——快速幂,该方法能够快速求出
a
b
a^b
ab,核心思想如下:
1、当b为偶数时,
a
b
a^b
ab可转化为
(
a
2
)
b
/
2
(a^2)^{b/2}
(a2)b/2;
2、当b为奇数时,
a
b
a^b
ab可转化为
(
a
2
)
b
/
2
(a^2)^{b/2}
(a2)b/2,再乘以
a
a
a。
public double Power(double base, int exponent) {
if(exponent == 0) return 1;
if(exponent == 1) return base;
boolean isN = false;
if(exponent < 0){
isN = true;
exponent = -exponent;
}
double result = Power(base*base, exponent / 2);
if(exponent % 2 == 1) result *= base;
return isN ? 1/result : result;
}
回到题目中,考虑底数为0、指数小于0、无效输入等情况,可以写成代码如下。
public double Power(double base, int n) {
double res = 1,curr = base;
int exponent;
if(n>0){
exponent = n;
}else if(n<0){
if(base==0)
throw new RuntimeException("分母不能为0");
exponent = -n;
}else{// n==0
return 1;// 0的0次方
}
while(exponent!=0){
if((exponent&1)==1)// 判断奇偶数
res*=curr;
curr*=curr;// 翻倍
exponent>>=1;// 右移一位
}
return n>=0?res:(1/res);
}