Problem
Implement pow(x, n), which calculates x raised to the power n (xn).
Method One
方法一和方法二都用到了快速幂
一开始又双叒一个一个乘了(像极了之前的平方根hhhhh),然后毫无疑问地超时。
第一种方法:
class Solution {
public:
double Pow(double x, long n) {
// 递归出口
if (n==1) return x;
// 递归
// Pos(x, n>>1);
double sum = Pow(x, n/2);
// 奇数时额外乘以x
// n&1
return n%2 ? sum*sum*x : sum*sum;
}
double myPow(double x, int n) {
// 避免整型无法存储
long nn = n;
// 特殊情况,x==1可以不要
if (nn==0||x==1) return 1;
// -1时输出倒数
return nn<0 ? 1/Pos(x, nn) : Pos(x, nn);
}
};
时间复杂度:O(logn)
空间复杂度:O(logn)
Method Two
第二种方法用到了快速幂。
试一下二进制与十进制的转换就可以发现这个规律:
∏x^二进制中为1的位置(为0的位置结果为1)
class Solution {
public:
double quickMul(double x, long long N) {
double ans = 1.0;
double x_contribute = x;
while (N > 0) {
// 二进制位为1时
if (N % 2 == 1) {
ans *= x_contribute;
}
x_contribute *= x_contribute;
N /= 2;
}
return ans;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};
时间:O(logn)
空间:O(1)
Method Three
换底公式。
exp(n*log(x));
(但是exp函数用到了内置的pow)