我正在研究一个递归递归问题:
实施pow(x, n),计算将 x 提升到幂 n (x ^ n)。
示例1:
Input: 2.00000, 10 Output: 1024.00000
示例2:
Input: 2.10000, 3 Output: 9.26100
示例3:
Input: 2.00000, -2 Output: 0.25000 Explanation: 2^-2 = 1/2^2 = 1/4 = 0.25
注意:
- -100.0 < x <100.0
- n 是一个32位带符号整数,范围为[−231,231 − 1]
我的二等分法
class Solution:
def myPow(self, x: float, n: int) -> float:
#base case
if n == 0: return 1
#recur case
else:
half = self.myPow(x, n//2) #floor
if n % 2 == 0: #even
return half**2
if n % 2 != 0: #odd
return x * (half**2)
运行TestCase时
def test_b(self):
x = 2.0
n = -2
answer = 0.25
check = self.solution.myPow(x, n)
self.assertEqual(answer, check)
报告错误:
DEBUG x: 2.0, n: -1
DEBUG x: 2.0, n: -1
DEBUG x: 2.0, n: -1
.......
DEBUG x: 2.0, n: -1
DEBUG x: 2.0, n: -1
DEBUG x: 2.0, n: -1
Fatal Python error: Cannot recover from stack overflow.
它在n=-1
停了下来,发现了尴尬的情况
In [10]: -1 // 2
Out[10]: -1
In [11]: -2 // 2
Out[11]: -1
修改后可以使用
class Solution:
def myPow(self, x: float, n: int) -> float:
"""
Runtime: 36 ms, faster than 99.70%
Memory Usage: 13.2 MB, less than 5.53%
"""
#base case
if n == 0: return 1
if n == -1: return 1/x
#recur case
else:
logging.debug(f"x: {x}, n: {n}")
half = self.myPow(x, n//2) #floor
if n % 2 == 0: #even
logging.debug(f"even: x: {x}, n: {n}, half:{half}")
return half**2
if n % 2 != 0: #odd
logging.debug(f"odd: x: {x}, n: {n}, half:{half}")
return x * (half**2)
但是,在阅读讨论和其他意见之后。我发现所有其他情况都更喜欢基本情况n < 0
一个清晰的例子:
class Solution(object):
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
if n == 0:
return 1
if n < 0:
return 1 /self.myPow(x, -n)
else:
partial = self.myPow(x, n//2)
result = partial * partial
if n % 2 == 1: #odd
result *= x
return result
我认为没有必要将负数n
更改为-n
,因为2**10 == 2**5 * 2** 5 and 2**-10== 2**-5 * 2**-5
由于人们比n < 0
更喜欢基本情况n == -1
,所以有什么好处?
答案 0 :(得分:2)
"not necessary to change negative n to-n"
:
我认为这是性能和精度的考虑。
所以我们更喜欢先做战俘,然后分开。