问题描述:求解a的b次方再对m取余数。
方法1:
int pow(int a,int b,int m){
int sum_a = a;
for(int i=0;i<b;i++)
sum_a *=a;
return sum_a % m;
}
性能分析:
时间复杂度:O(n)
空间复杂度:O(2^n)
无论从时间复杂度还是空间复杂度来看都是不理想的,尤其空间复杂度呈指数,无论变量sum_a定义成什么数据类型都极有可能溢出,所以此算法是不可取的。
方法2:
int pow(int a, int b, int m)
{
int res = 1;
while(b)
{
if(b & 1) //等价于 b % 2
res = res * a % m;
a = a * a % m;
b = b / 2;
}
return res;
}
解释:模运算满足分配率,(a*b)% m = ((a % m) * (b % m)) % m,所以将指数运算同模运算结合起来,将指数运算作为一系列的乘法运算,对于每次指数运算做一次模运算,(a*a*a*a*a*a*a)% m = ( ((a*a)%m) * ((a*a)%m) * ((a*a)%m) * (a % m) ) % m.
性能分析:
时间复杂度:O(logn)
空间复杂度:O(1)
无论是时间复杂度还是空间复杂度都比方法1好很多。
实例:( 5^9 ) % 3 = 2
( 5^9 ) % 3 = ( ((5*5)%3) * ((5*5)%3) * ((5*5)%3) * ((5*5)%3) * (5%3) ) % 3
= ( ( 1 * 1 * 1 * 1 ) * 2 ) % 3
= ( ( 1 * 1 ) * 2 ) % 3
= ( ( 1 * 2 ) % 3
= ( 2 ) % 3
= 2