乘法快速幂相关总结 & LeetCode - 50. Pow(x, n)
- 递归计算 (a n) % mod
- 非递归计算 (a n) % mod
- 计算 ( a * b ) % mod
- 配合 ( a * b ) % mod和乘法快速幂
- XYNUOJ - 1872. 次方求模题解
- LeetCode - 50. Pow(x, n)题解
递归计算 (a n) % mod
递归计算其实是更容易理解的:
- 为了求an,我们先递归去求出an/2,得到结果记录为
halfRes; - 然后如果
n为偶数,很好办,再乘以一个halfRes就可以了(再取模一下),也就是可以返回halfRes*halfRes; - 但是如果
n为奇数的话,就需要再乘以一个a,然后再返回;


代码:
1 | static long pow_mod(long a, long n, long mod) { |
非递归计算 (a n) % mod


假设一个整数是10,如何最快的求解10的75次方。
- ①
75的二进制形式为1001011; - ②
10的75次方 = **1064 × 108 × 102 × 101**; - 在这个过程中,我们先求出101,然后根据101求出102,再根据102求出104。。。。,最后根据1032求出1064,即
75的二进制数形式总共有多少位,我们就使用了多少次乘法; - ③ 在步骤②进行的过程中,把应该累乘的值相乘即可,比如**1064、108、102、101应该累乘,因为
64、8、2、1对应到75的二进制数中,相应位上是1;而1032、1016**、104不应该累乘,因为32、16、 4对应到75的二进制数中,相应位是0;
1 | static long pow_mod2(long a, long n, long mod) { |
使用a ^ 11来模拟一下计算过程:

计算 ( a * b ) % mod

1 | // 计算 (a * b) % mod |
配合 ( a * b ) % mod和乘法快速幂
可以使用非递归的乘法快速幂和上面的 (a*b) % mod 来计算快速幂,差别不大:
1 | // 计算 (a * b) % mod |
XYNUOJ - 1872. 次方求模题解
题目链接
题目

完全的模板题,三种方法都可以通过:
1 | import java.io.BufferedInputStream; |
LeetCode - 50. Pow(x, n)题解
题目链接
题目

解析
这个题目和普通的求幂不同的是:
- 其中
x(底数)是double类型的,且n是范围是Integer范围的(可正可负) : - 要注意的就是当
n为负数的时候,我们可以转换成求1.0 / pow(x,-n); - 还一个很重要的地方就是当
n = Integer.MIN_VALUE的时候要特殊处理,因为整形范围是-231到231-1,所以或者我们使用long来存转换的数,或者特殊判断一下;递归求解:
两种写法意思一样,第二种写法更加简洁:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Solution {
public double myPow(double x, int n) {
if (n > 0) {
return pow(x, n);
} else {
if (n == Integer.MIN_VALUE) {
return 1.0 / (pow(x, -(Integer.MIN_VALUE + 1)) * x); // MAX_VALUE = -(Integer.MIN_VALUE + 1)
}
return 1.0 / pow(x, -n);
}
}
public double pow(double x, int n) {
if (n == 0)
return 1;
double half = pow(x, n / 2);
if (n % 2 == 0)
return half * half;
else
return x * half * half;
}
}
1 | class Solution { |
非递归求解:
三种写法的意思都是一样,只不过处理Integer.MIN_VALUE的方式不同而已。
1 | class Solution { |
1 | class Solution { |
1 | class Solution { |