剑指Offer-12-数值的整数次方

题目

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

解析

思路一

大多数一看这题感觉很简单,我当时也是,直接调用Math库即可呀,可是面试考的不是对API的熟练的程度,而是对数据逻辑处理能力,所以思路一调库这个可以直接pass掉了。

思路二

那就自己造轮子把,于是你可能迅速的写下了如下代码:

    public static double Power2(double base, int exponent) {
        double res = 1.0;
        for(int i = 1; i <= exponent; i++) {
            res *= base;
        }
        return res;
    }

可是这样是不对的,因为未考虑如下几种情况:
1. 当exponent为负数时,上诉代码结果始终为1。
2. 当exponent为负数时,base是不能为0的。因为分母不能为0。

所以引出更加完备的思路三。

思路三

  1. 考虑到指数可能为负数
  2. 考虑到求负幂时,底数不能为0
  3. 考虑用logn的复杂度来求数的幂
    1. 递归形式
    2. 快速幂
递归形式

a n = { a n / 2 a n / 2 , n为偶数 a ( n 1 ) / 2 a ( n 1 ) / 2 a , n为奇数

正常我们求24次方,需要24次乘法。但是当我们知道12次方的时候,可以直接对12次方乘以自身得到24,按照这样思路,24 -> 12 -> 6 -> 3 -> 1。只需5次乘法即可。

    /**
     * 递归的形式求快速幂
     * @param base
     * @param exponent
     * @return
     */
    public static double recursivePow(double base, int exponent) {
        if(exponent == 0) {
            return 1;
        }
        if(exponent == 1) {
            return base;
        }
        double res = recursivePow(base, exponent >> 1);
        //这里可以看递归公式,即可明白
        if((exponent & 1) == 1) {
            res *= base;
        }
        return res;
    }
快速幂

这篇博文

总的代码

    /**
     * 完备的double型的整数幂次方函数
     * 这里用的快速幂思想
     * @param base
     * @param exponent
     * @return
     */
    public static double Power(double base, int exponent) {
        if(equal(base, 0.0) && exponent < 0) {
            throw new IllegalArgumentException("分母不能为0");
        }
        int absExponent = exponent < 0 ? -exponent : exponent;
        double res = 1;
        double t = base;
        while(absExponent != 0) {
            if((absExponent & 1) == 1) {
                res *= t;
            }
            t *= t;
            absExponent >>= 1;
        }
        return exponent < 0 ? 1.0 / res : res;
    }

    /**
     * 判断double型数据的是否相等
     * @param num1
     * @param num2
     * @return
     */
    public static boolean equal(double num1, double num2) {
        return num1 - num2 < 1e-8 && num1 - num2 > -1e-8;
    }

总结

考察如下两方面:
1. 判断程序员是否思维缜密
2. 对快速求幂次方的掌握程度

猜你喜欢

转载自blog.csdn.net/dawn_after_dark/article/details/80716070