LeetCode 50. Pow(x, n)
题目描述
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例 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
说明:
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。
解题
最简单的方法就是对x做乘法,总计乘以n次。那么能不能更快一点呢?对于n我们有:
n
=
∑
2
i
n=\sum 2^{i}
n=∑2i
所以:
x
n
=
x
∑
2
i
=
∏
n
2
i
x^{n} = {x^{\sum {2^{i}}} = \prod {n^{2^{i}}}}
xn=x∑2i=∏n2i
n
2
i
=
n
2
i
−
1
∗
n
2
i
−
1
n^{2^{i}} = n^{2^{i-1}}*n^{2^{i-1}}
n2i=n2i−1∗n2i−1
因此,对于连乘的每一项都可以使用平方计算,只需要计算
l
o
g
2
i
log_{2}{i}
log2i次,那么我们可以根据n的二进制来循环或递归,在循环或递归过程中:
1. 不断平方计算得到
n
2
i
n^{2^{i}}
n2i
2. 如果当前位为1,那么当前已求的值乘以
n
2
i
n^{2^{i}}
n2i,以实现最终子项连乘的目的
循环
class Solution {
public:
double myPow(double x, int n) {
const unsigned int temp = 1<<31;
unsigned int abs_n = temp&n ? (temp-(temp^n)) : n;
double val=1;
while (abs_n){
if (abs_n&1){
val *= x;
}
abs_n>>=1;
x*=x;
}
if (n < 0) return 1.0/val;
return val;
}
};
递归
class Solution {
private:
double myPow_inter(double x, unsigned int abs_n, double val){
if (abs_n==0) return val;
if (abs_n&1) val *= x;
x*=x;
abs_n >>= 1;
return myPow_inter(x, abs_n, val);
}
public:
double myPow(double x, int n) {
const unsigned int temp = 1<<31;
unsigned int abs_n = temp&n ? (temp-(temp^n)) : n;
if (n < 0) return 1.0 / myPow_inter(x, abs_n, 1);
return myPow_inter(x, abs_n, 1);
}
};