Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.
Example1:
a = 2
b = [3]
Result: 8
Example2:
a = 2
b = [1,0]
Result: 1024
题目大意:
给出一个数a和一个数组b,以及一个除数1337,求a^b mod 1337
解题思路:
最简单的解题方法就是先计算出b数组组成的一个整数n,然后求得a^n,最后求取a^n mod 1337,然而这里有个难点:
1,就是数组变成整数时可能远远大于可存储的最大数,;
2,a^n远远大于可存储的最大数,所以就需要迂回的解决这个问题。
对于这个问题其实有个快速幂算法即:
(ab) mod c=(a mod c)(b mod c)
若b是偶数,则有令
k=(a2)mod c
则前式为
(k(b/2))mod c
若b是奇数,则依旧令
k=(a2)mod c
,则前式为
(k(b/2)∗a)mod c
详情参看:http://blog.csdn.net/ghui23/article/details/51986719
代码实现(1)
下面是采用while循环实现的代码,然而提示超时,我也是醉了,第二种方法以递归的方式实现,成功提交,这就有点疑惑的,不知道为何,一般来说,循环应该比递归消耗的时间更少,除非leetcode计算的调用superpow函数一次所用的时间
public class Solution {
public boolean isNotZero(int[] x){
for(int i=x.length-1;i>=0;i--){
if(x[i]>0) return true;
}
return false;
}
public void div(int[] x,int y){
int tmp=0;
for(int i=0;i<x.length;i++){
x[i] += tmp*10;
tmp = x[i] % y;
x[i] = x[i] /y;
}
}
public int superPow(int a, int[] b) {
int c=1337;
int ans=1;
a=a%c;
while(isNotZero(b)==true)
{
if(b[b.length-1]%2==1)
ans=(ans*a) % c;
div(b,2);
a=(a*a) % c;
}
return ans;
}
}
解法(2)
采用递归方法,AC
public class Solution {
public boolean isNotZero(int[] x){
for(int i=x.length-1;i>=0;i--){
if(x[i]>0) return true;
}
return false;
}
public void div(int[] x,int y){
int tmp=0;
for(int i=0;i<x.length;i++){
x[i] += tmp*10;
tmp = x[i] % y;
x[i] = x[i] /y;
}
}
public int superPow(int a, int[] b) {
if(isNotZero(b)==false)
return 1;
boolean flag=false;
a=a%1337;
if(b[b.length-1]%2==1)
flag=true;
div(b,2);
int ans=superPow(a,b);
ans*=ans;
ans=ans%1337;
if(flag==true)
ans=(ans*a)%1337;
return ans;
}
}