一直听说过快速幂,一直没有用过。这下稍微有了点空闲时间,做个笔记自己看看。。
求一个数的n次幂常见的是n次循环。例如。
double Power(double base,int exponent)
{
bool flag=false;
double total=1;
if(exponent<0){
flag=true;
exponent=-exponent;
}
while(exponent--)
{
total=total*base;
}
return flag?1/total:total;
}
复杂度是O(n)。
快速幂算法是怎样的?
比如求5^13次方,分析如下:
①、13=1101(二进制形式)
②、1101
2^3*1+ 2^2*1 +2^1*0 + 2^0*1
设算式为 A=5^(2^3),B=5^(2^2),C=5^(2^1),D= 5^(2^0)
对应的位依次为 1 1 0 1
化简
5^13=A * B * D
可以看到如果对应二进制位为1.则其代表的算式会出现。并且D*D=C,C*C=B,B*B=A。
计算便可以这样来看。
一开始是D,判断D所属未位置为1,乘上D。D-->C
判断C所属位置为0,不乘C,C-->B。
判断B所属位置为1,乘B,B-->A。
判断A所属位置为1,乘A,结束。
该性质具有一般性。因为整数都可以拆分成二进制表示。
设base=D,ans=1。
从右到左依次从1101取值。如果为1,则ans*=base,否则不做变化。每轮更新base,由上面的性质知道base=base*base.则可以向上更新。
到此,所有困惑都明白了。得到如下代码。
class Solution {
public:
double Power(double base,int exponent)//底数作为一开始的D
{
bool flag=false;
double total=1;
if(exponent<0){
flag=true;
exponent=-exponent;
}
while(exponent)
{
if(exponent&1)//如果存在1,则乘上该值
{
total*=base;
}
exponent>>=1;
base=base*base;//更新底数
}
return flag?1/total:total;
}
};