Leetcode 372.超级次方
超级次方
你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。
示例 1:
输入: a = 2, b = [3]
输出: 8
示例 2:
输入: a = 2, b = [1,0]
输出: 1024
解题思想
这道题需要计算 a^b % c 的值,其中b非常的大,大到只能使用数组来表示。这道题是ACM里面常见的快速幂的解题方式,这其中有一个数学的推论,可以看我代码里附带的那个解释。
总之,这个公式的意思就是,(a*b)%c=(a%c)*(b%c),因此我们可以在每一步计算结果之后都这么处理,防止溢出。
第二个算法部分其实很容易理解,就是可以做类似于二分的分割,比如当b是偶数的时候,我们可以转化为计算a^(b/2)后再平方,而对于基础,则再乘一个a就可以,总之你看代码就知道了
1 public class Solution { 2 // 判断是否大于0 3 public static boolean morethanzero(int[] x){ 4 for(int i=x.length-1;i>=0;i--){ 5 if(x[i]>0) 6 return true; 7 } 8 return false; 9 } 10 //高精度除法 11 public static void div(int[] x,int y){ 12 int tmp=0; 13 for(int i=0;i<x.length;i++){ 14 x[i] += tmp*10; 15 tmp = x[i] % y; 16 x[i] = x[i] /y; 17 } 18 } 19 20 public static int superPow(int a, int[] b) { 21 if (morethanzero(b) == false) 22 return 1; 23 a=a%1337; 24 boolean isEven = false; 25 if(b[b.length-1] % 2 == 0) 26 isEven = true; 27 div(b,2); 28 int result = superPow(a,b); 29 result = result % 1337; 30 result*=result;//result由于div分成了两部分,现在把两部分合在一起 31 result = result % 1337; 32 if(isEven==false){ 33 result*=a;//奇数的话,再乘以a 34 result = result % 1337; 35 } 36 return result; 37 } 38 }