1 题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
示例1
2 解题思路
预处理:求 pow(b , n), 如果n为负数怎么解决?
例如求 x − 2 x^{-2} x−2 是不是可以转换成 ( 1 x ) 2 (\frac 1x)^2 (x1)2
于是,预处理代码如下:
double Power(double b, int n) {
if (n < 0) {
b = 1 / b;
n = -n;
}
}
2.1 暴力解题
循环n次,n个b相乘
class Solution {
public:
double Power(double b, int n) {
if (n < 0) {
b = 1 / b;
n = -n;
}
double ret = 1.0;
for (int i=0; i<n; ++i) ret *= b;
return ret;
}
};
时间复杂度:O(n)
空间复杂度:O(1)
2.2 递归法(快速幂)
假设我们求 x 8 x^8 x8,如果知道 x 4 x^4 x4,那么 x 8 = ( x 4 ) 2 x^8 = (x^4)^2 x8=(x4)2,所以 x n = ( x n 2 ) 2 x^n = (x^{\frac n2})^2 xn=(x2n)2
但是还有一个问题 如果n是偶数,上述公式即可
如果n是奇数, x n = ( x n 2 ) 2 ∗ x x^n = (x^{\frac n2})^2*x xn=(x2n)2∗x,例如 x 7 = ( x 3 ) 2 ∗ x x^7 = (x^3)^2*x x7=(x3)2∗x
代码如下:
class Solution {
public:
double q_power(double b, int n) {
if (n == 0) return 1.0;
double ret = q_power(b, n/2);
if (n&1) { // 奇数
return ret * ret * b;
}
else {
return ret * ret;
}
}
double Power(double b, int n) {
if (n < 0) {
b = 1 / b;
n = -n;
}
return q_power(b, n);
}
};
时间复杂度:O(logn),每次规模减少一半
空间复杂度:O(logn),递归栈,以为要记住logn个变量
2.3 非递归的快速幂
假设求 x 6 x^6 x6,已知6可以表示成二进制110
可以表示成 6 = 0 ∗ 2 0 + 1 ∗ 2 1 + 1 ∗ 2 2 6=0*2^0 + 1*2^1 + 1*2^2 6=0∗20+1∗21+1∗22,所以 x 6 x^6 x6可以表示成 x 6 = x 0 ∗ 2 0 + 1 ∗ 2 1 + 1 ∗ 2 2 = x 0 × x 1 ∗ 2 1 × x 1 ∗ 2 2 x^6 = x^{0*2^0 + 1*2^1 + 1*2^2} = x^0 × x^{1*2^1} × x^{1*2^2} x6=x0∗20+1∗21+1∗22=x0×x1∗21×x1∗22 所以,对于二进制数,遇到位数是1的就乘到答案中。
代码如下:
class Solution {
public:
double Power(double b, int n) {
if (n < 0) {
b = 1 / b;
n = -n;
}
double x = b; // 记录x^0, x^1, x^2 ...
double ret = 1.0;
while (n) {
if (n&1) {
ret *= x; // 二进制位数是1的,乘进答案。
}
x *= x;
n >>= 1;
}
return ret;
}
};
上述方法相对于遍历n的二进制位,是1就乘进结果
时间复杂度:O(logn),因为n的二进制位个数位logn
空间复杂度:O(1)