[leetCode]剑指 Offer 16. 数值的整数次方

在这里插入图片描述

解法一

此题需要关注边界问题:

  • 当为0,n<0 时会出现 0为底的情况
  • 对 int 型数据 -2147483648 求绝对值,结果仍为 -2147483648:参考

考虑到这两点后可以很快的用for循环实现o(n)的算法,但是为了降低时间复杂度可以使用递归或快速幂,以下代码使用递归求解。假设需要求一个数字的32次方,则需要知道其16次方。而16次方是8次方的平方,以此类推需要做5次乘法:

class Solution {
    public double myPow(double x, int n) {
        if(x == 0.0 && n < 0.0) return 0.0;
        long absExponent = n;
        if(absExponent < 0) absExponent = -(long)n;
        if(n < 0) return 1d / powWithAbsExponent(x,absExponent);
        return powWithAbsExponent(x,absExponent);
    }
    private double powWithAbsExponent(double base, long absExponent ){
        if(absExponent == 0)
            return 1;
        if(absExponent == 1)
            return base;
        double result = powWithAbsExponent(base, absExponent >> 1);
        result *= result;
        if((absExponent & 1) == 1)
            result *= base;
        return result;
    }
}

解法二 快速幂

把n转换为二进制,对x使用n的二进制进行展开即可求解:参考

class Solution {
    public double myPow(double x, int n) {
        if(x == 0 && n < 0) return 0.0;
        long absExponent = (long)n;
        if(absExponent < 0) absExponent = -(long)n;//先强转防止溢出
        if(n < 0) return 1d / powWithAbsExponent(x,absExponent);
        return powWithAbsExponent(x,absExponent);
    }
    private double powWithAbsExponent(double base, long absExponent ){//实现快速幂
        double res = 1.0;
        while(absExponent > 0){
            if((absExponent & 1) == 1){
                res *= base;   
            }
            absExponent = absExponent >> 1;
            base *= base;
        }
        return res;
    }
}
posted @ 2020-08-11 10:31  消灭猕猴桃  阅读(63)  评论(0编辑  收藏  举报