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
}
}