------------------------------------二刷2020/12/24--------------------------------
确实掌握了快速幂,可喜可贺可喜可贺
//位运算快速幂
class Solution {
public:
double myPow(double x, int n) {
long Special = n;
if(n < 0) return 1 / Pow(x, - Special);
return Pow(x, n);
}
double Pow(double x, long n) {
double temp = x ;
double ans = 1;
while(n) {
if(n & 1) ans*=temp;
temp*=temp;
n >>= 1;
}
return ans;
}
};
//二分法快速幂
class Solution {
public:
double myPow(double x, int n) {
long Special = n;
if(Special < 0)
return 1/Pow(x, -Special);
return Pow(x,n);
}
double Pow(double x, long n)
{
if(n == 0) return 1;
if(n == 1) return x;
double temp = Pow(x, n / 2);
if(n % 2 == 0) return temp * temp;
return temp * temp * x;
}
};
------------------------------------一刷-----------------------------------------------
题目描述
解法一 二分快速幂
定义临时变量temp,将递归的复杂度缩减到O(logN)
class Solution {
public:
double myPow(double x, int n)
{
long jud=n;
if (jud<0) {
return 1/myPow(x,-jud);
}
return Pow(x,jud);
}
private:
double Pow(double x, long n)
{
if (n==0) return 1;
if (n==1) return x;
double half=Pow(x, n / 2);
if (n%2==0)
return half*half;
else
return half*half*x;
}
};
这题有个坑,写的时候倒在最后几个测试用例好几次…
要考虑到int类型的整数的负数的最小值的绝对值是比最大值的绝对值大1的,这是组原里面的知识。
然而后面看到一个更厉害的递归…不知道作者是谁
class Solution {
public:
double myPow(double x, int n)
{
if(n==0)
return 1;
if(n==1)
return x;
double temp=myPow(x,n/2);
if(n%2==0)
return temp*temp;//正偶数
if(n>0)
return temp*temp*x;//正奇数
else
return temp*temp/x;//负奇数
}
};
解法二 位运算快速幂
将幂转化为二进制表示,再求出分解后各项总的乘积
比较懒,借用Krahets的解释
快速幂-百度百科
class Solution {
public:
double myPow(double x, int n) {
if(n == 0) return 1;
if(n == 1) return x;
long jud = n;
double ans=1;
if(n < 0)
{
x=1/x;
jud=-jud;
}
while(jud)
{
if((jud & 1) == 1) ans *= x;//幂的二进制最低位为1说明此项为x^2(i-1)*1
//if((jud & 1) == 0) ans*=1;//幂的二进制最低位为1说明此项为x^2(i-1)*0=1
x *= x;//每项x的值都为前一项的平方
jud >>= 1;//幂右移,进行下一位是1或者是0的判断
}
return ans;
}
};
时间复杂度O(logN):n转化为2进制有几位就算几次
空间复杂度O(1)