比如我们在求解a的b次方的时候,最笨的方法就是递归实现,但是他的复杂度巨大(a连乘b次),快速幂可以达到O(logn),效率大大降低,为了加深一下记忆,我们来一起分析一下这个快速幂是怎么回事
比如我们在求4的11次方的时候,应用快速幂的概念。将11可以装换成二进制的1011,所以我们4的11次方可以表示位4的(1011)次方,进一步转换可以表示为4的(1000)次方*4的(0010)次方*4的(0001)次方----》4的8次方*4的2次方*4的一次方。
然后我们再来介绍一下左移,右移,和&是什么个意思:
正数的左移动和右移动都是补0的,而负数的左移是补0,右移是补1
&是与的意思,&1是与1(0001)进行逻辑与操作。
接下来我们直接来分析代码。
int poww(int a, int b) {
int ans = 1, base = a;
while (b != 0) {
if (b & 1 != 0){
ans *= base;
}
base *= base;
b >>= 1;
}
return ans;
}
从最低位开始(b&1),如果是1的话代表是个有效位,去乘对应的base(base初始值为a,每次循环都会平方,解释见注解1),比如第一次循环(1011)最后一位是1,条件成立,则ans=ans*base=1*4.。。然后将b右移动(0101)最后一位还是1,ans=4^1*16=4^1 * 4^2(这里解释一下4^1,为啥是1呢,注解2)后面的过程一样。但是到第三次循环的时候,最后一位变成了0,判断条件不成立,不存在有效位,ans不能记录,但是base还得进行,右移动操作也得进行。
注解1:要理解base=base*base;因为base* base=base^2,下一步再乘就是base^2 * base^2=base^4,然后base^4 * base^4=base^8,这样对应着二进制的每一位。
注解2:因为最后一位二进制表示的话不就是2^0次方,不就是1嘛。然后倒数第二位是2^1=2
由于作者口才拙劣…………下面教授无敌看懂大法。哪张纸和笔,谢谢过程,自己体会一下就可以懂了。