leetcode 50 题解 快速幂学习
方案一 暴力直接循n次 ---- 毫无意外TLE
class Solution {
public:
double myPow(double x, int n) {
double res=1.0;
if(n>=0)
{
while(n>0){
res=res*x;
n--;
cout<< x;
}
return res;
}else if(n<0){
while (n<0)
{
res=res*x;
n++;
}
return 1/res;
}else
return x;
}
};
整数递归的写法
所以这就是快速幂的基本思路求a ^ b
我们已知 2^3 求 2^6,不就是 2^3 * 2^3嘛。快速幂就是这个原理。
那有同学问了遇到奇数怎么办?2 ^ 5??
那不就是 2 * 2 ^ 4 这不就成了嘛。
1)当b是奇数时,那么有 a^b = a * a^*(b-1)
2)当b是偶数时,那么有 a^b = a^(b/2) * a^(b/2)
class Solution {
public:
double myPow(double x, int n) {
if(n==0){
return 1;
}else if(n%2==1){
return x*myPow(x,n-1);
}else {
return myPow(x,n/2)*myPow(x,n/2);
}
}
};
快速幂学习
假设求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(n)级,快速幂能做到O(logn)
首先把b写成它的二进制形式,设该二进制数第i位的权值为2^(i-1),i * 2^(i-1)是每一次要做的乘方次数
那么假设b=11,11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1=2³+2¹+2º,所以:a¹¹= a^2º* a ^2¹ * a^2³
参考来源
由于是二进制,很自然地想到用位运算这个强大的工具:&和>> &运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&10为偶,x&11为奇。 >>运算比较单纯,二进制去掉最后一位,不多说了,先放代码再解释
。
class Solution {
public:
double myPow(double x, int n) {
double ans=1.0;
double base=x;
int b=n;
while(n!=0)
{
// 幂次是1 有贡献
if(n&1){
ans=ans*base;
}
// base 要频繁
base=base*base;
//这里 要写成 / 号 因为写成>> 在负数的情况下 会陷入死循环 -1 的补码全是11111
n=n>>1;
//cout<< n;
}
printf("%x",-1);
return b>=0 ? ans : 1/ans;
}
};