Skip to content

Latest commit

 

History

History
66 lines (49 loc) · 2.27 KB

50.Pow(x,n).md

File metadata and controls

66 lines (49 loc) · 2.27 KB

方法一:递归。

指数可能有两种:自然数或者负数,对于负数情况依然可以按照自然数情况计算,只是最后需要1.0/res即可。

xx2x4x8x16x32x64

​ xx*2x4x9x19x38→*x77

当我们试图从左往右计算时,无法确定当前是直接平方,还是平方后依然要乘以x。为了解决这种困境,我们采用从右往左的方式计算,每次只需要判断指数是奇数还是偶数,如果是偶数直接将结果平方,否则平方后再乘x

class Solution {
    public double myPow(double x, int n) {
        long N = n;
        // 自然数 or 负数,两种情况
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }

    public double quickMul(double x, long N) {
        if (N == 0) {
            return 1.0;
        }
        double y = quickMul(x, N / 2);
        // 指数是偶数 or 奇数 两种情况
        return N % 2 == 0 ? y * y : y * y * x;
    }
}

方法二:迭代。

在迭代方法中就需要从左往右计算,但是刚刚说了从左往右计算所面临的困难,所以尝试另一种做法。

通过计算和观察发现,77的二进制值是(1001101)2,而x77 = x * x4 * x8 * x64 ,所以得出结论:

​ 若 n = 2i0 + 2 i1 + .... + 2in

​ 则 x = x2i0 * x2i1 * ... * x2in

class Solution {
    public double myPow(double x, int n) {
        long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }

    public double quickMul(double x, long N) {
        
        double res = 1.0;
        double x_contribute = x;
        while (N > 0) {
            // 判断指数的最后一位是否是1,x_contribute就表示当前位的2^n
            if ((N & 1) != 0) {
                res *= x_contribute;
            }
            x_contribute *= x_contribute;
            // y
            N /= 2;
        }
        return res;
    }
}