快速幂
传统的幂运算,是对底数进行连乘,时间复杂度为o(n),例如:2^ 13 = 2* 2 * 2……*2,连乘十三次。但是我们可以通过增加底数,减少指数的做法,降低时间复杂度。从而能够实现复杂度为o(logn)的幂运算。还是以2^13为例,13的二进制为1101,因此2的13次方可以分解成以下形式:
和13的二进制1101相对比,只要二进制为1的位,就有权重,权重为2^(i-1),i表示第几位,1101从右到左,依次为第1位,第2位,第3位,第4位。
下面的工作就是如何确定二进制中的哪一位为1,这里可以利用位运算中的&和>>运算。
由于1的二进制除了第一位是1,其他的全是0,因此可以利用n&1是否为0来判断n的二进制的当前最低位是否为1,如果n&1等于0,说明当前n的最低位不为1。
利用右移运算>>来逐位读取,然后每次判断是否为1。
Python实现
应用一:求base的exponent次方
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# -*- coding:utf-8 -*- class Solution: def Power(self, base, exponent): # write code here flag=1 re=1 tmp=base if exponent==0: #等于0的情况 return 1 if exponent<0: #小于0的时候,设置一个flag,用于返回的时候做判断 flag=0 exponent=abs(exponent) while exponent>0: #大于0的情况 if exponent&1==1: re=re*tmp #判断当前位是否为1,如果是的话,把之前的幂乘到结果中 exponent=exponent>>1 #右移动一位就是除以2 tmp=tmp*tmp #2^6=(2*2)^3 return re if flag else 1/re
应用二:快速幂取模
在算幂的模的时候,比如2^ 64 mod(10086),不必要算64次乘法,只需要首先算2^2 mod 10086,再算2 ^ 4在算2 ^8
一般情况下,即将指数进行二进制分解,如果二进制不为0的位,则进行乘法运算,具体的算法如下
复制代码
1
2
3
4
5
6
7
8
9
10
11def fastExpMod(b, e, m): result = 1 while e != 0: if (e&1) == 1: # ei = 1, then mul result = (result * b) % m e >>= 1 # b, b^2, b^4, b^8, ... , b^(2^n) b = (b*b) % m return result
最后
以上就是合适洋葱最近收集整理的关于快速幂详解及其Python实现的全部内容,更多相关快速幂详解及其Python实现内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复