Fast Power
原題鏈接:http://lintcode.com/en/problem/fast-power/#
Calculate the an % b where a, b and n are all 32bit integers.
Example
For 231 % 3 = 2
For 1001000 % 1000 = 0
Challenge
O(logn)
Tags Expand
SOLUTION 1:
實際上這題應該是suppose n > 0的。
我們利用 取模運算的乘法法則: http://baike.baidu.com/view/4887065.htm
(a * b) % p = (a % p * b % p) % p (3)
將 a^n % b 分解為 (a^(n/2) * a^(n/2) * (a)) %b = ((a^(n/2) * a^(n/2))%b * (a)%b) %b = ((a^(n/2)%b * a^(n/2)%b)%b * (a)%b) %b
實現如下:
注意2個base case: n = 0 n = 1都要特別處理。因為n = 1時,會分解出一個pow(a, b, 1),這個會不斷循環調用。

1 class Solution { 2 /* 3 * @param a, b, n: 32bit integers 4 * @return: An integer 5 */ 6 /* 7 * @param a, b, n: 32bit integers 8 * @return: An integer 9 */ 10 public static int fastPower(int a, int b, int n) { 11 // write your code here 12 long ret = pow(a, b, n); 13 14 return (int) ret; 15 } 16 17 // suppose n > 0 18 public static long pow(int a, int b, int n) { 19 if (a == 0) { 20 return 0; 21 } 22 23 // The base case. 24 if (n == 0) { 25 return 1 % b; 26 } 27 28 if (n == 1) { 29 return a % b; 30 } 31 32 long ret = 0; 33 34 // (a * b) % p = (a % p * b % p) % p (3) 35 ret = pow(a, b, n / 2); 36 ret *= ret; 37 38 // 這一步是為了防止溢出 39 ret %= b; 40 41 if (n % 2 == 1) { 42 ret *= pow(a, b, 1); 43 } 44 45 // 執行取余操作 46 ret = ret % b; 47 48 return ret; 49 } 50 };
SOLUTION 2:
或者你也可以把pow(a, b, 1)直接寫為a % b. 以下解法把base case: n = 1就拿掉了。

1 // SOLUTION 2: 2 // suppose n > 0 3 public static long pow(int a, int b, int n) { 4 if (a == 0) { 5 return 0; 6 } 7 8 // The base case. 9 if (n == 0) { 10 return 1 % b; 11 } 12 13 long ret = 0; 14 15 // (a * b) % p = (a % p * b % p) % p (3) 16 ret = pow(a, b, n / 2); 17 ret *= ret; 18 19 // 這一步是為了防止溢出 20 ret %= b; 21 22 if (n % 2 == 1) { 23 ret *= (a % b); 24 } 25 26 // 執行取余操作 27 ret = ret % b; 28 29 return ret; 30 }
GITHUB:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/lintcode/math/FastPower.java