题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。保证base和exponent不同时为0。无需考虑越界情况。
实现思路
- 方法一:常规的for循环遍历,时间复杂度为O(n)。
- 方法二(较好理解):二分幂,时间复杂度为O(logn)。比如:求220,只需要递归求210,25,22,21,20即可,因为210*210=220,25*25 = 210,(22*22)*2 = 25,21*21 = 22,(20*20)*2 = 21,20 = 1(递归终止条件)。可得到以下递推公式:
b a s e e x p o n e n t = { b a s e e x p o n e n t / 2 ∗ b a s e e x p o n e n t / 2 base%2 = 0 b a s e ∗ b a s e e x p o n e n t / 2 ∗ b a s e e x p o n e n t / 2 base%2 = 1 base^{exponent}= \begin{cases} base^{exponent/2} * base^{exponent/2}& \text{base\%2 = 0}\\ base*base^{exponent/2} * base^{exponent/2}& \text{base\%2 = 1} \end{cases} baseexponent={baseexponent/2∗baseexponent/2base∗baseexponent/2∗baseexponent/2base%2 = 0base%2 = 1 - 方法三:快速幂,时间复杂度为O(logn)。最好配合下面的快速幂代码来理解,exponent每次迭代减半,幂数为偶数累乘base,即base *= base,幂数为奇数同时还累乘结果,即result *= base,注:result初始化为1。为什么要这样乘呢?比如:求220,20的二进制为:10100 = 22 + 2 4 = 4 + 16,有220 = 24 * 216。220(幂数为偶数执行base *= base,得base2),210(幂数为偶数执行base *= base,得base4),25(可以看到前面执行了两组base *= base,刚好就是base4 = 24。幂数为奇数执行result *= base,base *= base。此时result = 24,base = base8),22(幂数为偶数执行base *= base,得base16),21(可以看到前面执行了四组base *= base,刚好得到base16 = 216。幂数为奇数执行result *= base,base * = base。此时result = 24 * 216 = 220,base的值无需再管),20(幂数为0,跳出循环的条件)。
代码实现
二分幂实现:
public double Power(double base, int exponent) throws Exception
{
//处理特殊情况
if(base == 0 && exponent == 0)throw new Exception("base和exponent不能同时为0");
if(base == 0)return 0;
if(exponent == 0)return 1;
double result = 0;
result = Power(base, Math.abs(exponent) / 2); //递归求解,这里exponent取绝对值,为了避免当exponent为负数时,每个递归的result都要被1除。
if(exponent % 2 != 0) //递归完后执行累乘,如果幂数是奇数
{
result = base * result * result;
}
else
{
result = result * result;
}
if(exponent < 0) //只会在第一层递归执行,处理exponent为负数的情况
{
result = 1 / result;
}
return result;
}
快速幂实现:
public double Power1( int base, int exponent ) throws Exception
{
//处理特殊情况
if(base == 0 && exponent == 0)throw new Exception("base和exponent不能同时为0");
if(base == 0)return 0;
if(exponent == 0)return 1;
double result = 1;
boolean isNegative = false;
if(exponent < 0)isNegative = true;
exponent = Math.abs(exponent);
while( exponent != 0 )
{
if( (exponent & 1) == 1 )//与b%2相同,判断奇偶性,奇数就累乘进结果。
{
result *= base;
}
base *= base; //累乘base
exponent >>= 1;//与b/2相同
}
if(isNegative) //处理exponent为负数的情况
{
System.out.println(1/result);
return 1/result;
}
else
{
System.out.println(result);
return result;
}
}
参考:https://blog.csdn.net/tcm_zhangpeng/article/details/49737509