实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x^n )。
1、暴力算法
x个n相乘即可
需要注意
1、如果n是负数,那么就是正数个n的1/x相乘
2、越界处理
double myPow(double x, int n) {
//处理n为负数的情况
long long N = n;//把n变为长整型是处理越界的常用手段
if (N < 0)
{
x = 1 / x;
N = -N;
}
double ans = 1;
for (long long i = 0; i < N; i++)
ans = ans * x;
return ans;
}
2、分治算法
考虑二分法
第一种情况:
(考虑是2的幂)如果我们要计算 x^{64}
如果想要计算64次方,那么先计算32次方,而32就需要先计算16次方,而16次方需要计算8次方…最后只需要计算x的2次方。
这样从 x 开始,每次直接把上一次的结果进行平方,计算 6 次就可以得到 最终值,而不需要对 x乘64次。
第二种情况:
(考虑不是2的幂)如果我们要计算x的77次方,那么
从右往左看,如果本身的n是奇数的话,那么上面的栈帧返回要多乘一个n,比如给上层传了一个77,上层收到后,先对77/2向下取整为38,然后我往下层传的时候传递2的38次方的平方再乘上一个x
第三种情况:
(考虑n是负数)
取n的绝对值,计算的时候比如说2的-64次方就是1/(2^64),也就是按正常算,在最后结果的时候用1除以结果得到最终的结果
归纳一下
结束条件,由于n每次都取0,那么最终的边界就是为0(1/2=0)
由于每次递归都会使得指数减少一半,因此递归的层数为 O(log n)
代码
1、暴力破解法
double myPow(double x, int n) {
//处理n为负数的情况
long long N = n;//把n变为长整型是处理越界的常用手段
if (N < 0)
{
x = 1 / x;
N = -N;
}
double ans = 1;
for (long long i = 0; i < N; i++)
ans = ans * x;
return ans;
}
2、分治算法
class Solution {
public:
double quickMul(double x, long long N) {
if (N == 0) {
return 1.0;
}
double y = quickMul(x, N / 2);
return N % 2 == 0 ? y * y : y * y * x;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};