LeetCode 50. Pow(x, n)(求x的n次方)

329 阅读2分钟

leetcode.com/problems/po…

Discus:www.cnblogs.com/grandyang/p…

Implement pow(x, n), which calculates x raised to the power n (i.e., xn).

Example 1:

Input: x = 2.00000, n = 10
Output: 1024.00000

Example 2:

Input: x = 2.10000, n = 3
Output: 9.26100

Example 3:

Input: x = 2.00000, n = -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25

Constraints:

  • -100.0 < x < 100.0

  • -231 <= n <= 231-1

  • -104 <= xn <= 104

解法一:

直接使用 Math 库的 pow() 方法。

class Solution {
    fun myPow(x: Double, n: Int): Double {
        return Math.pow(x, n.toDouble())
    }
}

解法二:

暴力循环求解,不能 AC。

class Solution {
    fun myPow(x: Double, n: Int): Double {
        var result: Double = 1.0

        when {
            n > 0 -> {
                for (i in 1..n) {
                    result *= x
                }
            }
            n < 0 -> {
                for (i in n..-1) {
                    result /= x
                }
            }
            else -> {
                result = 1.0
            }
        }
        return result
    }
}

解法三:

我们可以用递归来折半计算,每次把n缩小一半,这样n最终会缩小到0,任何数的0次方都为1,这时候再往回乘,如果此时n是偶数,直接把上次递归得到的值算个平方返回即可,如果是奇数,则还需要乘上个x的值。还有一点需要引起注意的是n有可能为负数,对于n是负数的情况,我可以先用其绝对值计算出一个结果再取其倒数即可,之前是可以的,但是现在 test case 中加了个负2的31次方后,这就不行了,因为其绝对值超过了整型最大值,会有溢出错误,不过可以用另一种写法只用一个函数,在每次递归中处理n的正负,然后做相应的变换即可,代码如下:

class Solution {
    fun myPow(x: Double, n: Int): Double {
        if (n == 0) {
            return 1.0
        }
        val half = myPow(x, n / 2)
        return when {
            n % 2 == 0 -> {
                half * half
            }
            n > 0 -> {
                half * half * x
            }
            else -> {
                half * half / x
            }
        }
    }
}

解法四:

这道题还有迭代的解法,让 tempN 初始化为 n 的绝对值,tempX 初始化为 x,如果 n 为负数,则 tempX 初始化为 1/x,然后看 tempN 是否是 2 的倍数,不是的话就让 result 乘以 tempX。然后 tempX 乘以自己,tempN 每次循环缩小一半,直到为 0 停止循环。参见代码如下:

class Solution {
    fun myPow(x: Double, n: Int): Double {
        var result: Double = 1.0
        var tempX :Double = x
        var tempN :Long = n.toLong()

        if (n < 0) {
            tempX = 1 / x
            tempN = Math.abs(n.toLong())
        }

        while (tempN >0 ) {
            if (tempN.and(1) == 1L) {
                result *= tempX
            }
            tempX *= tempX
            tempN = tempN.shr(1)
        }
        return result
    }
}
class Solution {
    fun myPow(x: Double, n: Int): Double {
        var result: Double = 1.0
        var tempX: Double = x
        var tempN: Long = n.toLong()

        if (n < 0) {
            tempX = 1 / x
            tempN = Math.abs(n.toLong())
        }

        while (tempN != 0L) {
            if (tempN % 2 != 0L) {
                result *= tempX
            }
            tempX *= tempX
            tempN /= 2
        }
        return result
    }
}