参考了网上一个比较妙的解法。
要注意的地方有:
1) 当n为负数时,可以用1/x^(-n)。但要注意-MIN_VALUE转正时会溢出;
2) while循环内会记录factor=x^(2n)(不管n&0x1是否为1),这样就避免了冗余计算。
3) while循环内,当n&0x1=1时,就让result*=factor。比如说3^10=3^(2^1) * 3^(2^3)。
#include <iostream>
using namespace std;
double myPow(double x, int n) {
if (n==0) return 1.0;
bool neg=false;
if (n<0) {n=-(n+1); neg=true;} //note MIN_MAX may overflow
double result=1.0;
double factor=x;
while(n) {
if (n & 0x1) result*=factor;
n=n>>1;
factor*=factor; //record x^(2n)
}
if (neg)
return 1.0/result/x;
else
return result;
}
int main()
{
cout<<myPow(2.0, 10)<<endl;
cout<<myPow(2.1, 3)<<endl;
return 0;
}
解法2:递归
double myPow(double x, int n) {
if (n == 0) return 1.0;
double result;
bool neg=false;
if (n<0) {
neg=true;
n=-(n+1); //note MIN_MAX may overflow
}
if (n % 2 == 0) {
double tmp = myPow(x, n / 2);
result = tmp * tmp;
} else {
double tmp = myPow(x, n / 2);
result = tmp * tmp * x;
}
if (neg) result=1.0/result/x;
return result;
}
递归和非递归的简化版本如下(没有考虑n为负的情况):
//递归
int power(int x, int n) {
if (n == 0) return 1;
if (n % 2 == 0) {
int tmp = power(x, n / 2);
return tmp * tmp;
} else {
int tmp = power(x, n / 2);
return tmp * tmp * x;
}
}
//非递归
int power(int x, int n) {
int ans = 1, base = x;
while (n != 0) {
if (n % 2 == 1) {
ans *= base;
}
base *= base;
n = n / 2;
}
return ans;
}
怎么来理解这个非递归算法呢?实际上我觉得这个非递归算法和递归算法并不是一一对应的。它是基于这么一个事实:即x ^ n 就是当n写成2进制时,把它的二进制位数上是1的那些数找出来,算出其对应的x次方,然后求其全部乘积即可。打个比方: n = 11,写成2进制是1011,对应11=1+2+8(注意不是index 0,1,3)。所以x^11=x^1*x^2*x^8,即我们求出x, x ^ 2, x^ 8,然后全部相乘即可。这也就是为什么ans *= base只是当n 为奇数才执行(因为我们只需要找出2进制里面那些是1的数)。但我们不管n是否为奇数,都要执行base*=base操作,这样,就可以求下一个2^n的值。
三刷:利用x^n = (1/x)^(-n)就可以了。
class Solution {
public:
/**
* @param x: the base number
* @param n: the power number
* @return: the result
*/
double myPow(double x, int n) {
long long m = n;
if (m < 0) {
m = -m;
x = 1/x;
}
double res = 1.0, prod = x;
while (m) {
if (m & 0x1) res *= prod;
m >>= 1;
prod *= prod;
}
return res;
}
};