题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路一:本题以前也做过,只不是没有总结。有很多方法,效率不一样而已,第一种方法分情况讨论,然后采用分支递归,如果直接用循环,效率非常低O(n),现在分情况,分支递归,效率提高一半。考虑了底数和指数为0的特殊情况之后,就分指数是负数还是正数来讨论,如果是正数,那么分奇数还是偶数,因为分支递归,分成两条路,如果是偶数,刚好平分,如果是奇数,有一半要多一次运算。即
n为偶数,a^n=a^n/
2
*a^n/
2
;n为奇数,a^n=(a^(n-
1
)/
2
)*(a^(n-
1
/
2
))*a
时间复杂度O(logn)
如果指数x是负数的话,那么运算结果是1/result^(-x)。代码如下:
代码一:
java:
public class Solution {
public double Power(double base, int exponent) {
if(base==0)
return 0;
if(exponent==0)
return 1;
if(exponent==1)
return base;
if(exponent>0&&exponent%2==0){
return Power(base,exponent/2)*Power(base,exponent/2);
}else if(exponent>0){
return Power(base,exponent/2)*Power(base,exponent/2+1);
}
/* if(exponent<0&&exponent%2==0){
base=1/base;
exponent=-exponent;
return Power(base,exponent/2)*Power(base,exponent/2);
}else{
base=1/base;
exponent=-exponent;
return Power(base,exponent/2)*Power(base,exponent/2+1);
}*/
return 1/Power(base,0-exponent);
}
}
js:
function Power(base, exponent)
{
if(base==0)
return 0;
if(exponent==0)
return 1;
if(exponent==1)
return base;
if(exponent>0&&exponent%2==0){
return Power(base,parseInt(exponent/2))*Power(base,parseInt(exponent/2));
}else if(exponent>0){
return Power(base,parseInt(exponent/2))*Power(base,parseInt(exponent/2)+1);
}
return 1/Power(base,0-exponent);
// write code here
}
思路二:最快的运算就是进行二进制运算了,有时候用二进制去解题是真的很快,很不可思议。本题也可以用二进制去解。比如3^13.
13的二进制为1101
指数的二进制 1 1 0 1
要乘的数 x a^8 a^4 a^2 a
最终的结果y y=y*x y=y*x y=a*x y=a*x (y0为底数,注意不同位置,x取值不一样,同时每一次y相乘之后被取代)
以上思路可能描述的不是很好,这也是“快速幂”的思想。大一搞ACM的时候,不懂快速幂为啥是这样子的,大二学了算法,我才明白为啥了,这个思路真的很难想清楚,不过可以记住这个模板,套模板也是可以的。注意:快速幂也需要考虑指数为0或者底数为0 这种特殊情况分开讨论。至于怎么实现上面思路,可以通过&按位与运算来判断是否为1,通过右移来进行计算,具体看代码。
码二:
java
public class Solution {
public double Power(double base, int exponent) {
if(base==0)
return 0;
if(exponent==0)
return 1;
if(exponent==1)
return base;
int ex=exponent;
double result=1;
if(ex<0)
exponent=-exponent;
while(exponent!=0){
if((exponent&1)==1)
result*=base;
base*=base;
exponent>>=1;
}
return ex>0?result:1/result;
}
}
以上代码可以作为快速幂的模板,可以直接套用。