超級次方
阿新 • • 發佈:2021-12-05
372. 超級次方
你的任務是計算 ab 對 1337 取模,a 是一個正整數,b 是一個非常大的正整數且會以陣列形式給出。
示例 1:
輸入:a = 2, b = [3]
輸出:8
示例 2:
輸入:a = 2, b = [1,0]
輸出:1024
示例 3:
輸入:a = 1, b = [4,3,3,8,5,2]
輸出:1
示例 4:
輸入:a = 2147483647, b = [2,0,0]
輸出:1198
我們都知道
an+m == an + am
(an)m == anm
我們先忽略取模操作看一個例子
比如求 4235 那麼輸入應該是 4 {2 , 3 , 5}
變為求 ((42
先求 res = 42
迴圈 res = res10 * 43 --> 此時 res = (42)10 * 43
迴圈 res = res10 * 45 --> 此時 res = ((42)10 * 43)10 * 45 --> res = ((42)10)10 * ( 43)10 * 45
得到答案 , 退出
總結 : 迴圈--前面得到的值開 10 次方再乘以上後一位的值 , 作為下一次計算的值 , 迴圈到陣列最後一位
加上取模操作方法不變
此時我們可以確保指數冪的位置為個位 ( n <= 9)
但是當底數很大時 , 如果直接使用 Math.pow(a , n) % 1337 或者 Math.pow(a % 1337 , n) % 1337 都會溢位
因為它是直接在 Math.pow(a , n) 或 Math.pow(a % 1337 , n) 就溢位了 , 我們無法在控制在每一步冪次時對數字取模限制其大小
所以要自己定義一個 myPow 遞迴方法
需要降冪 , 否則會出現溢位
那麼我們可以從陣列高位進行計算 , 即先求 ab[0]
上式可以變為 ab[0]/2 * ab[0]/2
但是要考慮 b[0] 奇偶性
- 偶數時 , ab[0] == ab[0]/2 * ab[0]/2
- 奇數時 , ab[0] == ab[0]/2 * ab[0]/2 * a
每一步遇到求次方或乘數後要對結果取模 %1337 (題中已給出)
改為以下
- 偶數時 , ab[0] % 1337 ==( ab[0]/2
- 奇數時 , ab[0] == (( ab[0]/2 * ab[0]/2 ) % 1337 * (a % 1337 )) % 1337
java 程式碼
int base = 1337;
//輔助方法
public int myPow(int a, int n) {
if (n == 0) {
return 1;
}
//遞迴, 確保每層返回後得到的 halfPow 都是對 1337 取模後的值
int halfPow = myPow(a, n / 2) % base;
int ret = (halfPow * halfPow) % base;
if ((n & 1) == 1) {
return (ret * (a % base)) % base;
}
return ret;
}
//主要方法
public int superPow(int a, int[] b) {
int ans = 1;
for (int i = 0; i < b.length; i++) {
int p = myPow(a, b[i]);
ans = ((myPow(ans, 10) % base) * (p % base)) % base;
}
return ans;
}