问题:

  • 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

解决

//1.快速幂+递归(O(logN)/O(logN))
class Solution {
    public double myPow(double x, int n) {
        //二次:x*x,三次:x*x*x......n次:x*x*...*x,n个x相乘
        // 使用递归的思想,每次都是前面的;两倍

        long N=n;           //防止-2^32溢出

        return N>=0? quikPow(x,N):1.0/quikPow(x,N);      //如果n大于等于零,则是正常的乘积,相反的话就取倒数

    }
    public double quikPow(double x,long N){
        if(N==0) return 1.0;                            //递归的结束条件,当N=0时,任何数的0次访都为0

        double y=quikPow(x,N/2);                        //定义y=上一次乘积

        return N%2==0? y*y:y*y*x;                       //本次的两个乘积相乘,如果n为偶数则y*y,为奇数y*y*x
    }
}
//2.快速幂+迭代(O(logN)/O(1))
class Solution{
    public double myPow(double x,int n){
        long N=n;
        return N>=0? quikPow(x,N):1.0/quikPow(x,-N);
    }
    public double quikPow(double x,long N){
        double ans=1.0;               //作为贡献x的赋值,什么是贡献的x:例如x^9->x^4,其中就贡献了一个x
        double x_contribute=x;      //贡献值最初是x
        while(N>0){                 //只要N>0,就一直要检测是否有贡献
            if(N%2==1){             //获取N的二进制最后一位是不是1,如果是1就要平方一次
                ans *=x_contribute;
            }
            x_contribute*=x_contribute;     /// 将贡献不断地平方,因为N后面的每次贡献前面以及贡献的都要平方
            N/=2;                   //舍弃当前N的二进制最低为,保证每次只用判断N二进制的最后一位即可
        }
        return ans;                 //返回所有的贡献的全部平方即可

    }

}

总结;

  • 快速幂+递归利用后面的乘积等于两个前面的乘积相乘 x^36 = x^18 * x^18
  • 快速幂+迭代的方法运用了找规律,发现x的n次幂的值总是等于x的(N的二进制1出现位置的值)次方!!