LeetCode-50-powx-n
实现 pow(x, n)
,即计算 x
的 n
次幂函数。
示例 1:
输入: 2.00000, 10
输出: 1024.00000
示例 2:
输入: 2.10000, 3
输出: 9.26100
示例 3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:
- -100.0 < x < 100.0
- n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/powx-n
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1:
func myPow(x float64, n int) float64 {
if n >= 0 {
return pow(x, n)
}
return 1.0 / pow(x, -n)
}
// 按照定义x**n = n个x相乘
func pow(x float64, n int) float64 {
y := 1.0
for i := 0; i < n; i++ {
y = y * x
}
return y
}
打完收工,结果
执行结果:超出时间限制
最后执行的输入:
0.00001
2147483647
改进
上述算法做了n次乘法,直接超时了,能不能减少运算量呢
思考:
- 如果n是2的倍数,\(x^{2k}=x^k*x^k\),也就是可以减少一半的计算量,这个称之为快速幂
- 如果n不是2的倍数,\(x^{2k+1}=x^{2k}*x\),可以转化成第一种情况
func myPow(x float64, n int) float64 {
if n >= 0 {
return pow(x, n)
}
return 1.0 / pow(x, -n)
}
func pow(x float64, n int) float64 {
// 递归出口
if n == 0 {
return 1.0
} else if n == 1 {
return x
}
// x^{2k} = x^{k} * x^{k}
// x^{2k+1} = x^{2k} * x
if n % 2 == 0 {
ans := pow(x, n / 2)
return ans * ans
} else {
return x * pow(x, n - 1)
}
}
执行结果:通过
执行用时:0 ms, 在所有 Go 提交中击败了100.00%的用户
内存消耗:2 MB, 在所有 Go 提交中击败了66.05%的用户
能不能更给力一点
上述解法使用了递归,需要额外的栈空间,可以改成迭代
- 我们可以把n拆分 \(n = 2^i + 2^j + 2^k + ... + 2^0\)
- \(x^n = x^{2^i + 2^j + 2^k + ... + 2^0} = x^{2^i} * x^{2^j} * x^{2^k} * ... * x^{2^0}\)
- 例如 \(9 = b1001 = 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0\),可得\(x^9=x^8*x^1\)
// 非递归的解法
func pow(x float64, n int) float64 {
ans := 1.0
for i := n; i != 0; i /= 2 {
if i % 2 != 0 {
ans *= x
}
x *= x
}
return ans
}
执行结果:通过
执行用时:0 ms, 在所有 Go 提交中击败了100.00%的用户
内存消耗:2 MB, 在所有 Go 提交中击败了100.00%的用户