题目来自LeetCode,链接:面试题16. 数值的整数次方。具体描述为:实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
示例1:
输入: 2.00000, 10
输出: 1024.00000
示例2:
输入: 2.10000, 3
输出: 9.26100
示例3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
这道题还是比较明显的二分法的题目,因为一个数x
的n
次方可以转化为一个数的n/2
次方的平方(奇数的情况下再多乘上一个x
),所以可以方便地用递归实现。时间复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn),空间复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn)(递归栈所需的空间)。
JAVA版代码如下:
class Solution {
public double myPow(double x, int n) {
if (n == 0 || x == 1.0) {
return 1.0;
}
if (n == 1) {
return x;
}
if (n == -1) {
return 1 / x;
}
double half = myPow(x, n / 2);
double extra = myPow(x, n % 2);
return half * half * extra;
}
}
提交结果如下:
![](https://img-blog.csdnimg.cn/20200505001329535.png)
然后要用递推来实现的话需要一点数学推导,假设
b
m
…
b
i
…
b
1
b_{m}\dots b_{i}\dots b_{1}
bm…bi…b1为n
的二进制表示,则可以把数n
表示为
n
=
b
m
×
2
m
−
1
+
⋯
+
b
i
×
2
i
−
1
+
⋯
+
b
1
×
2
0
n=b_{m}\times 2^{m-1}+\cdots+b_{i}\times 2^{i-1}+\cdots+b_{1}\times 2^{0}
n=bm×2m−1+⋯+bi×2i−1+⋯+b1×20,考虑到
b
i
b_{i}
bi只能取0或1,所以
x
n
=
x
b
m
×
2
m
−
1
+
⋯
+
b
i
×
2
i
−
1
+
⋯
+
b
1
×
2
0
=
∏
b
i
=
1
x
2
(
i
−
1
)
x^{n}=x^{b_{m}\times 2^{m-1}+\cdots+b_{i}\times 2^{i-1}+\cdots+b_{1}\times 2^{0}}=\prod_{b_{i}=1}x^{2(i-1)}
xn=xbm×2m−1+⋯+bi×2i−1+⋯+b1×20=∏bi=1x2(i−1)。也就是说只要在循环过程中判断当前n
的末尾是否为1(即某个
b
i
b_{i}
bi是否为1),是的话在结果上乘上
x
2
(
i
−
1
)
x^{2(i-1)}
x2(i−1)即可。时间复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn),空间复杂度为
O
(
1
)
O(1)
O(1)。
JAVA版代码如下:
class Solution {
public double myPow(double x, int n) {
if (n == 0 || x == 1.0) {
return 1.0;
}
if (n == 1) {
return x;
}
if (n < 0) {
// n取到整数最小值的话直接取反会溢出,所以这里需要除以2
if ((n & 1) == 0) {
double tmp = myPow(1 / x, -(n / 2));
return tmp * tmp;
}
else {
double tmp = myPow(1 / x, -(n / 2));
return tmp * tmp / x;
}
}
double result = 1.0;
while (n > 0) {
if ((n & 1) == 1) {
result *= x;
}
x *= x;
n >>= 1;
}
return result;
}
}
提交结果如下:
![](https://img-blog.csdnimg.cn/20200505003051258.png)
Python版代码如下:
class Solution:
def myPow(self, x: float, n: int) -> float:
if n == 0 or x == 1.0:
return 1.0
if n < 0:
return self.myPow(1 / x, -n)
result = 1.0
while n > 0:
if (n & 1) == 1:
result *= x
x *= x
n >>= 1
return result
提交结果如下:
![](https://img-blog.csdnimg.cn/20200505003617139.png)