[LeetCode]75. Pow(x,n)幂运算

Implement pow(xn).

Subscribe to see which companies asked this question

解法1:最简单的即是n个x直接相乘,毫无疑问会超时Time Limit Exceeded

class Solution {
public:
    double myPow(double x, int n) {
        if(x < 0.000001) return 0;
        if(n == 0) return 1;
        if(n < 0) return 1.0 / myPow(x, -n);
        
        double res = 1.0;
        for(int i = 0; i < n; ++i)
            res *= x;
        return res;
    }
};

解法2:考虑pow(4,12),可以这样计算:pow(4,12)=pow(4,8)*pow(4,4),而pow(4,8)可以通过pow(4,1)-->pow(4,2)-->pow(4,4)-->pow(4,8)这样计算,pow(4,4)同样可以通过可以通过pow(4,1)-->pow(4,2)-->pow(4,4)计算得到。即在计算到某次幂pow(x,k)的时候,若当前幂次的平方pow(x,2k)不会大于结果(通过2k<=n来判断),则直接平方。因此可以写出如下代码:

class Solution {
public:
    double myPow(double x, int n) {
        if (x < 0.000001) return 0;
        if (n == 0) return 1;
        if (n < 0) return 1.0 / myPow(x, -n);

        double res = 1.0;
        while (n > 0) {
            double f = x;
            int loop = 1;
            while ((loop << 1) <= n) {
                f *= f;
                loop <<= 1;
            }
            n -= loop;
            res *= f;
        }
        return res;
    }
};

这样虽然一定程度上减少了运算次数,但是正如上面例子展现的,仍然会有不少的冗余计算。同样在LeetCode中提交后会超时Time Limit Exceeded。可以使用map<double,int>记录下计算过的幂值,第一次循环后后面的所有值都可以通过查表得到,这样可以减少重复计算。

class Solution {
public:
    double myPow(double x, int n) {
        if (x == 0) return 0;
        if (n == 0) return 1;
        if (n < 0) return 1.0 / myPow(x, -n);
        vector<double> power;
        
        double res = 1.0;
        double f = x;
        int loop = 1;
        power.push_back(f);
        while ((loop << 1) <= n) {
            f *= f;
            power.push_back(f);
            loop <<= 1;
        }
        n -= loop;
        res *= f;
        bitset<sizeof(int) * 8> powb(n);
        for (int i = 0; i < 32; ++i) {
            if (powb[i] == 1)
                res *= power[i];
        }
        return res;
    }
};

但是这种方法会出现 Memory Limit Exceeded。因为输入指数为int型,实际vector<double>最大长度为32,是常数复杂度。时间复杂度也在常数级别。不知题目限定空间复杂度在什么级别。

解法3:考虑使用二分搜索。如果n为偶数,则pow(x,n)=pow(x,n/2)*pow(x,n/2),如果n是奇数则再乘个x。这样递归下去,直到n==0。

class Solution {
public:
    double myPow(double x, int n) {
        if (x == 0) return 0;
        if (n == 0) return 1;
        if (n < 0) return 1.0 / power(x, -n);
        return power(x, n);
    }
private:
    double power(double x, int n) {
        if (n == 0) return 1;
        double half = power(x, n / 2);
        double res = half * half;
        return n % 2 == 0 ? res : res * x;
    }
};
原文地址:https://www.cnblogs.com/aprilcheny/p/4959942.html