• 剑指 Offer 16. 数值的整数次方


    剑指 Offer 16. 数值的整数次方

    1.结果

    执行结果:通过显示详情>

    执行用时:0 ms ,在所有Java提交中击败了100.00%的用户

    内存消耗:40.7MB ,在所有Java提交中击败了44.53%的用户

    通过测试用例: 304/304

    2.时间花费

    一个小时,动态规划超内存,实际上并没有二分,相当于遍历一轮

    看答案,用递归能过。

    3.思路

    • 思路一:动态规划

      虽然采用了动态规划,每次按对半相乘,但是还是算了n次,因此时间复杂度是O(n)

    • 思路二:递归

      时间复杂度O(log n)

    • 快速幂算法

      二分相乘,时间复杂度O(log n)

      主要用到了这个思路,这个很牛逼。分治法思想。

    4.code

    4.1 code1

    class Solution {
        public double myPow(double x, int n) {
            boolean flag = false;
            if (n < 0){
                flag = true;
                n = -n; 
            }
            if( n == 0){
                return 1;
            }else if( n == 1){
                return flag?1/x:x;
            }
            //动态规划 f(n) = f(n/2) * f(n/2)
            // f(0) = 1
            // f(1) = x
            // f(2) = f(1) * f(1)
            // f(3) = f(1) * f(2)
            // f(4) = f(2) * f(2)
    
            //这里有个整数最大值的问题,应该不要搞到n+1,后面单独乘一次,
            //但是当n为整型最大值时,又会有内存的问题
            double[] re = new double[n];  
            re[0] = 1;
            re[1] = x;
            for (int i = 1; i < n; i++){
                int num = i/2;
                if(i % 2 == 1){
                    re[i] = re[num] * re[num + 1];
                }else{
                    re[i] = re[num] * re[num];
                }
            }
            // System.out.println(Arrays.toString(re)) ;
            re[n-1] = re[n-1] * x;
            if(flag) return 1/re[n-1];
            else return re[n-1];
        }
    }
    

    4.2 code2

    4.3 code3

    这里long N = n;很关键,可以解决指数在整型范围的最大值和最小值问题,

    尤其是,最小值**-2147483648**,转正数时会报错

    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 ans = 1.0;
        // 贡献的初始值为 x
        double x_contribute = x;
        // 在对 N 进行二进制拆分的同时计算答案
        while (N > 0) {
            if (N % 2 == 1) {
                // 如果 N 二进制表示的最低位为 1,那么需要计入贡献
                ans *= x_contribute;
            }
            // 将贡献不断地平方
            x_contribute *= x_contribute;
            // 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
            N /= 2;
        }
        return ans;
    }
    

    我自己的代码【效果和答案很接近,时间也是接近0】

     public double myPow(double x, int n) {
            // 使用二分相乘
            // 3^13 = 3x (3^2)^6
            //      = 3x (9^2)^3 = 3x 81^3
            //      = 3x81 x(81^2)^1
            // 也就是先取单,然后底平方,指数减半
            // 以此类推
             if ( x == 1) return x;
             if ( n ==-2147483648 ){
                 if (x == -1) return 1;
                 else return 0;
            }
            if (n == -2147483648) return 0;
         	boolean flag = false;
            if (n < 0) {
                flag = true;
                // 当n = -2147483648时,取绝对值,会超过整型范围
                n = -n;
                System.out.println(n);
    
            }
            if (n == 0) {
                return 1;
            } else if (n == 1) {
                return flag ? 1 / x : x;
            }
            double result = 1;
            double base = x;
            System.out.println("result" + "\t\t" + "base" + "\t\t" + "n");
            while (n > 1) { //这里可以大于0,然后省掉return上面那句
                if (n % 2 == 1) {
                    // 表示是奇数,出一个底,更新指数
                    result = result * base;
                    n = n - 1;
                } else {
                    // 表示指数是偶数,底平方,指数减半
                    base = base * base;
                    n = n / 2;
                }
                System.out.println(result + "\t\t" + base + "\t\t" + n);
            }
            result = result * base; // while(n > 0)时,可省略这句
            return flag ? 1 / result : result;
    
        }
    
    
  • 相关阅读:
    腾讯云微服务平台 TSF 异地多活单元化能力重磅升级
    linux驱动25:阻塞型I/O
    EPB功能开发与测试(基于ModelBase实现)
    MATLAB遗传算法求解生鲜货损制冷时间窗碳排放多成本车辆路径规划问题
    论文复现笔记
    高压功率放大器原理和应用场合介绍
    Tenable Nessus 8.15.5 (Unix, Linux, Windows) -- #1 漏洞评估解决方案
    【限时免费】20天拿下华为OD笔试之【双指针】2023Q1A-最长的元音字符串【欧弟算法】全网注释最详细分类最全的华为OD真题题解
    面向对象高级一(static 继承)
    JSP useBean动作
  • 原文地址:https://blog.csdn.net/qq_37774098/article/details/127097164