zoukankan      html  css  js  c++  java
  • [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;
        }
    };
  • 相关阅读:
    Java基础学习——异常机制与集合的结合练习
    公司标签
    【JS语法糖】常见的几种JS语法糖
    webstorm批量替换
    webstorm 全局搜索快捷键_IntelliJ 的搜索和全局搜索怎么用
    存放缓存的三种方式 Redis、Memcache和MongoDB的区别
    Airtest学习(二)Airtest-Selenium 点击 断言 生成报告
    使用git克隆指定分支的代码
    nodejs v16.x 或更高版本不支持 Fibers
    使用 nvm 管理多个版本的 nodejs 和 npm,nvm的命令合集
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4959942.html
Copyright © 2011-2022 走看看