剑指offer第十二题
题目如下
题目分析
直接 pow(base,exponent) 就可以干掉这个题目
但这就没有意义了,
这个题的考点应该就是在指数是负数的时候怎么计算,数学还行的话,这题还是很简单的,当然,我门对次方问题都会想到快速幂。在后面的一篇博客中,我们会对快速幂进行介绍
先来看一下普通的直接幂
class Solution {
public:
double Power(double base, int exponent) {
double a=1.0;
if(base==0) return 0;
if(exponent==0) return 1;
if(exponent<0) base=1.0/base;
while(exponent){
a*=base;
exponent=(exponent>0)?(--exponent):(++exponent);
}
return a;
}
};
我们来看一下什么是快速幂
其实快速幂和合成大西瓜就很像
同学们应该玩过合成大西瓜吧,就是两个小瓜可以合成一个更牛逼的瓜,就是1+1==大写的1,更加支楞了。
那么幂运算为什么不能这样呢?
我乘两次为什么不直接乘一个二次方呢?
我乘两次二次方为什么不直接乘一个四次方呢?
有的同学可能觉得有点意思了,那我们就来看看快速幂的模板,解释都在注释里了
举个例子
32=2 * 2 * 2 * 2 *2;32等于2的五次方
5转化成二进制就是1001;
所以32可以转化成2的四次方 乘以 2的一次方
这样就减少了乘法的次数,在一个很大次方的时候达到运算时间大大缩减的效果
long long fastPower(long long base, long long power) {
long long result = 1;
while (power > 0) {
if (power & 1) {
//此处等价于if(power%2==1)
result = result * base % 1000;
}
power >>= 1;//此处等价于power=power/2
base = (base * base) % 1000;
}
return result;
}
这里是快速幂模板
运用到上面的优化如下
class Solution {
public:
double Power(double base, int exponent) {
double a=1.0;
if(base==0) return 0;
if(exponent==0) return 1;
if(exponent<0) {
base=1.0/base;
exponent*=(-1);
}
while(exponent){
if(exponent&1){
a=a*base;
}
exponent>>=1;
base*=base;
}
return a;
}
};