LeetCode 50
实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,\(x^n\) )。
- \(-100.0 < x < 100.0\)
- \(-2^{31} <= n <= 2^{31} - 1\)
- n 是一个整数
- 要么 x 不为零,要么 n > 0 。
- \(-10^4 <= x^n <= 10^4\)
由于 n 很大,所以不能暴力计算这个值,需要用到快速幂算法。
如何快速计算 \(x^8\) ?
\( x \to x^2 \to x^4 \to x^8 \)
从 x 开始,不断对自身平方,重复三次即可得到 \(x^8\)。
如何快速计算 \(x^{15}\) ?
\( x \cdot x^2 \cdot x^4 \cdot x^8 = x^{15} \)
在平方的过程中,把这些数全部相乘,即可得到 \(x^{15}\)。
如何快速计算 \(x^{13}\) ?
\( x \cdot x^4 \cdot x^8 = x^{13} \)
在平方的过程中,把 \(x, x^4, x^8\) 相乘,即可得到 \(x^{13}\)。
如何知道要把哪些数相乘?
把 n 看作二进制数,从低到高遍历二进制数,遇到 1 就和 x 的幂相乘。不断右移二进制数,右移前看最低位是否为 1。
\( 13 = 1101_{(2)} \)
如何处理 n < 0 的情况?
把 n 转换成 -n,把 x 转换成 1/x,就转换成了 n >= 0 的情况。
代码实现
double myPow(double x, int N) {
double ans = 1;
long long n = N;
if (n < 0) { // x^-n = (1/x)^n
n = -n;
x = 1 / x;
}
while (n) { // 从低到高枚举 n 的每个比特位
if (n & 1) { // 这个比特位是 1
ans *= x; // 把 x 乘到 ans 中
}
x *= x; // x 自身平方
n >>= 1; // 继续枚举下一个比特位
}
return ans;
}
时间复杂度:\(O(\log\lvert n \rvert)\)