【LeetCode题解】50. Pow(x, n)

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:

-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/powx-n
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

九牛二虎之力写出了又臭又长的代码,最下面有copy评论区6的飞起的解

class Solution {
    public double myPow(double x, int n) {
        /**
        保存[x^2, x^4, x^8.....]
        n拆成二进制形式:将n依次匹配并减去已匹配的 
        如n=11 即为 n=8+2+1
        2^11 = (2^8)*(2^2)*(2^1)
        */
        if(n == -2147483648){//不能直接去绝对值
            return myPow(x,-1)*myPow(x,n+1);
        }
        boolean flag_x = false;
        if(x==-1){//否则x=-1且n极大时候会出错,这里直接判断
            return n%2==0?1d:(-1d);
        }
        boolean flag_n = false;//幂是否为负数
        if(n == 0 || x == 1d){
            return 1d;
        }else if(n<0){
            flag_n = true;
        }
        n = Math.abs(n);
        int rank = 1;
        double pows= x;
        Map<Integer,Double> m = new HashMap<>();//可以改进为数组或List
        m.put(0,1d);
        m.put(rank,pows);
        while(n>=rank){//等于不要遗漏,否则会死循环
            pows = pows*pows;
            if(pows == 0){//中间值=0
                return 0d;
            }else if(pows == 1){//中间值=1
                return 1d;
            }else if(pows>Double.MAX_VALUE && flag_n){//分母已经极大,直接返回0
                return 0;
            }
            rank *= 2;
            m.put(rank,pows);
        }
        rank /= 2;
        double ret = m.get(rank);
        n -= rank;
        while(n>0){
            rank /= 2;
            if(n>=rank){//等于不要遗漏,否则会死循环
                ret *= m.get(rank);
                n -= rank;
            }
        }
        return flag_n?(1/ret):ret;
    }
}

评论有个很强的解:思路非常6,自作主张加了注释

class Solution {
    public double myPow(double x, int n) {
        double res = 1.0;
        for(int i = n; i != 0; i /= 2){
           //折半时 如果是偶数直接折半,如果是奇数,会丢失一个x,补齐多乘一个x
            if(i % 2 != 0){//就算n是2的幂也一定会在i=1的时候触发
                res *= x;
            }
            x *= x;
        }
        return  n < 0 ? 1 / res : res;
    }
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值