这是第13篇算法,力扣链接
实现 pow(x, n) ,即计算
x
的整数n
次幂函数(即,xn
)。示例 1:
输入:x = 2.00000, n = 10 输出:1024.00000示例 2:
输入:x = 2.10000, n = 3 输出:9.26100示例 3:
输入:x = 2.00000, n = -2 输出:0.25000 解释:2-2 = 1/22 = 1/4 = 0.25
这道题最先想到的是暴力求解,但是n的取值范围是,显然暴力一定会超时或者不是最优解。
那优先会想到优化方案就是二分法,分而治之来减少遍历的次数,比如可以拆成,当然,可以在拆。
二分法有两种思路,一种是迭代,一种是递归,但是不管是迭代还是递归他们的调用逻辑都是一样的,分开处理正负的场景。
func myPow(x float64, n int) float64 {
if n < 0 {
x = 1 / x
return doPow(x, -n)
} else {
return doPow(x, n)
}
}
在doPow里面有着不同的实现。这里的根本逻辑是区分奇偶,偶数场景很简单,取余后为0,则返回half*half的值,而奇数场景可能多了个x,即half*half*x
方法一:递归实现
func myPow(x float64, n int) float64 {
if n < 0 {
x = 1 / x
return doPow(x, -n)
} else {
return doPow(x, n)
}
}
func doPow1(x float64, n int) float64 {
if n == 0 {
return 1
}
half := doPow1(x, n/2)
if n%2 != 0 {
return half * half * x
} else {
return half * half
}
}
方法二:迭代实现
func myPow(x float64, n int) float64 {
if n < 0 {
x = 1 / x
return doPow(x, -n)
} else {
return doPow(x, n)
}
}
func doPow(x float64, n int) float64 {
result := 1.0
calculate := x
for n > 0 {
if n%2 == 1 {
result *= calculate
}
calculate *= calculate
n /= 2
}
return result
}