数值的整数次方
题目出处https://www.acwing.com/problem/content/26/
算法标签:模拟、快速幂。
这是一道比较简单的算法题,要求不使用c++自带的幂函数来计算base的exponent次方,并将结果返回。
根据题目要求,可以确定以下变量的范围
Base[double]
Exponent[int]
Pow(base,exponent)[double]
题目看起来很简单,但是当abs(exponent)的值非常大的时候,很有可能会TLE。
这是最简单的暴力做法:时间复杂度O(n)
class Solution {
public:
double Power(double base, int exponent) {
if(!exponent)return 1;
if(exponent<0){
base = 1.0/base;
exponent *= -1;
}
double temp = base;
while(exponent-->1)base *= temp;
return base;
}
};
指数为0时,结果为1。
若指数<0,把底数变成倒数,将指数取正。
再对base乘(指数-1)次temp,因为原先base就是1次,所以要减1次。
例:base = 2,exponent = 3;(3 -->1)会执行两次,最终结果就是222=8
很明显,此方法无法通过这个样例,以该复杂度最多需要计算2的32次。
下面引入一个新的方法。
快速幂:时间复杂度O(log2n),
这样最多需要进行32次计算。
class Solution {
public:
double Power(double base, int exponent) {
double temp;
if(!exponent)return 1;
if(exponent<0){
temp = 1.0/base;
exponent *= -1;
}
else temp = base;
base = 1;
while(exponent>0){
if(exponent&1)base *= temp;
exponent >>= 1;
temp *= temp;
}
return base;
}
};
指数为0时,返回1.
指数 <0时,把底数变成倒数,对指数取正。
Temp用于保存base方便计算,base变为1,也就是base的0次。
Exponent%2 与exponent&1效果等价,Exponent /= 2 与exponent>>=1效果等价。
位运算的速度远远大于其它运算,所以采用位运算。
Exponent在运行过程中实际被分解为了反向的二进制数。
例:base = 1.47,exponent = 38,根据代码,会得到以下数据
base = 1,exponent会被分解为0 1 1 0 0 1,temp = 1.47,理论答案是1.47的38次。
Exponent的六次数据分别与1.47的1、2、4、8、16、32次等价
最后的base就是1.47的(2+4+32)次,即1.47的38次,即最终答案。