leetcode----50. Pow(x, n)

链接:

https://leetcode.com/problems/powx-n/

大意:

给定一个double型的x,以及一个整数n。求x^n。从他的例子可以看到:保留的是5位小数,也就是说0.000001将会被转成0... 例子:

leetcode----50. Pow(x, n)_第1张图片

思路:

采用分治以及递归的思想解决,思想与之前的一个题解求两数的商:https://blog.csdn.net/smart_ferry/article/details/88740052 类似,具体思路看代码注释

代码:

 

class Solution {
    public double myPow(double x, int n) {
        // x为1或0的两种特殊情况
        if (x == 1 || x == 0)
            return x;
        // x == -1 并且 n为偶数的情况
        if (x == -1 && n % 2 == 0)
            return 1;
        // x == -1 并且 n为奇数的情况
        if (x == -1 && n % 2 != 0)
            return -1;
        // n为非负数的情况
        if(n >= 0)
            return helper(x, n, 1, true);
        else 
            return 1 / helper(x, -(long)n, 1, false);
    }
    // positive记录原给定的n为正还是负,用于快速跳出迭代计算   这里的n为long型是为了确保在myPow中n为Integer.MIN_VALUE时取反不溢出
    public double helper(double x, long n, double curV, boolean positive) {
        if (n == 0)
            return curV;
        int curN = 0;
        double curX = x;
        while (curN * 2 + 1 <= n) {
            curV *= curX;
            // 在计算时,如果发现所给次数为正并且当前得到的值的绝对值已经比0.00001小,则直接返回该值
            if (positive && Math.abs(curV) < 0.00001)
                return 0;
            // 在计算时,如果发现所给次数为负并且当前得到的值的绝对值已经比100000小(因为例子是给了5位小数....),则返回Double.MAX_VALUE
            if (!positive && Math.abs(curV) > 100000)
                return Double.MAX_VALUE;
            // curX每次变为原来的平方时,curV就已经乘了x^(2^(curN + 1) - 1)
            // 比如  一开始 curV = 1,curN = 0,curX = x
            // 则一次迭代之后, curV = x(相比与一开始的1,乘了 x^1) curX = x ^ 2  curN = 1
            // 下一次迭代后, curV = x * x^2 = x ^ 3(相比于一开始的1,乘了x^3)  curX = x ^ 4 curN = 2
            // 再下一次迭代, curV = x ^ 3 * x ^ 4 = x ^ 7 (相比于一开始的1,乘了x^7)  curX = x ^ 8 curN = 3
            curX *= curX;
            curN = curN * 2 + 1;
        }
        return helper(x, n - curN, curV, positive); // 消除尾递归  提升程序效率
    }
}

结果:

leetcode----50. Pow(x, n)_第2张图片

结论: 

这个题目除了需要想到使用分治+递归的方法之外,还得考虑各种边界情况以及更早跳出循环的条件,另外还得考虑最小整数取绝对值后溢出的问题。 

 

你可能感兴趣的:(leetcode,leetcode,分治)