幂运算,即次方运算,例如计算 的值即是幂运算,在实现的时候我们往往是这样写的:
int __pow(int a,int b){
int ans = 1;
while(b--){
ans *= a;
}
return ans;
}
其中a是底数,b为指数。从时间复杂度上分析这个算法的复杂度是O(n)级别,咋一看好像好很快,但是往往在比赛、做题的时候都需要处理指数很大运算,例如 ,即是 ,这个时候如果用上面的算法来计算的话,就要循环一百万次,程序就会超时。这个时候快速幂算法就呼之欲出了,先放代码实现:
int __poww(int a,int b){
int ans = 1;
while(b){
if(b & 1 != 0){
ans *= a;
}
a *= a;
b >>= 1;
}
return ans;
}
快速幂算法的原理是通过将指数拆分成几个因数相乘的形式,来简化幂运算。在我们计算 的时候,普通的幂运算算法需要计算13次,但是如果我们将它拆分成 ,再进一步拆分成 只需要计算4次。嗯?哪来的4次?,别急,接着看。
这种拆分思想其实就是借鉴了二进制与十进制转换的算法思想,我们知道13的二进制是1101,可以知道:
实现的代码已经给出,原理就是利用位运算里的位移“>>”和按位与“&”运算,代码中 b & 1其实就是取b二进制的最低位,用来判断最低位是0还是1,再根据是0还是1决定乘不乘,不理解的话联系一下二进制转换的过程。b >>= 1其实就是将b的二进制向右移动一位,就这样位移、取最低位、位移、取最低位,这样循环计算,直到指数b为0为止,整个过程和我们手动将二进制转换成十进制是非常相似的。普通幂算法是需要循环指数次,也就是指数是多少就要循环计算多少次,而快速幂因为利用了位移运算,只需要算“指数二进制位的位数”次,对于13来说,二进制是1101,有4位,就只需要计算4次,快速幂算法时间复杂度是O(logn)级别,对于普通幂需要计算一百万次的来说,快速幂只需要计算6次,这是速度上质的飞跃,但是需要多注意溢出的问题。