我从leetcode获取此代码。
class Solution(object):
def myPow(self, x, n):
if n == 0:
return 1
if n == -1:
return 1 / x
return self.myPow(x * x, n / 2) * ([1, x][n % 2])
此代码用于实现poe(x, n)
,这意味着Python中的x**n
。
我想知道为什么它可以实现pow(x, n)
。
它看起来没有意义......
我理解
if n == 0:
and
if n == -1:
但核心代码:
self.myPow(x * x, n / 2) * ([1, x][n % 2])
真的很难理解。
BTW,此代码仅适用于Python 2.7。如果要在Python 3上进行测试,则应更改myPow(x*x, n / 2) * ([1, x][n % 2])
到
myPow(x*x, n // 2) * ([1, x][n % 2])
答案 0 :(得分:4)
递归函数用于计算数字的幂(最可能是整数,非负数或-1
幂),如您所料(如x = 2.2
和n = 9
)。
(这似乎是针对Python 2.x
编写的(由于n/2
预期结果为integer
而不是n//2
))
最初的returns
是非常简单的数学运算。
if n == 0:
return 1
if n == -1:
return 1 / x
当权力为0
时,您返回1
,然后权力为-1
,则返回1/x
。
现在下一行包含两个元素:
self.myPow(x * x, n/2)
and
[1, x][n%2]
第一个self.myPow(x * x, n/2)
只是意味着您希望通过对有力数字0
x
)提升到其中的一半>
(最有可能通过减少所需的乘法次数来加速计算 - 想象一下如果你有计算2^58
的情况。通过乘法,你必须乘以58
次的数字但是如果你每次都把它分成两部分并递归地解决它,那么你的操作数量会减少。
示例:
x^8 = (x^2)^4 = y^4 #thus you reduce the number of operation you need to perform
在这里,您将x^2
作为递归中的下一个参数(即y
)并递归执行,直到幂为0
或-1
。
下一个是你得到两个分开的力量的模数。这是为了解决奇数的情况(即,当幂n
为奇数时)。
[1,x][n%2] #is 1 when n is even, is x when n is odd
如果n
为odd
,那么通过执行n/2
,您会在此过程中失去一个x
。因此,您必须将self.myPow(x * x, n / 2)
与x
相乘来弥补。但如果您的n
不是奇数(偶数),则不会丢失一个x
,因此您不需要将结果乘以x
而是1
。
说明性地:
x^9 = (x^2)^4 * x #take a look the x here
但
x^8 = (x^2)^4 * 1 #take a look the 1 here
因此,这个:
[1, x][n % 2]
是将前一个递归乘以1
(对于偶n
个案例)或x
(对于奇n
个案例)并且相当于三元表达式:< / p>
1 if n % 2 == 0 else x
答案 1 :(得分:0)
这是分而治之的技术。上面的实现是一种计算取幂的快速方法。在每次调用时,一半的乘法被消除。
假设n是偶数,x ^ n可以写成如下(如果n是奇数,则需要一次额外的乘法)
x^n = (x^2)^(n/2)
or
x^n = (x^n/2)^2
上面显示的功能实现了第一个版本。它也很容易实现第二个(我删除了下面的递归基本情况)
r = self.myPow(x,n/2)
return r * r * ([1, x][n % 2])
答案 2 :(得分:0)
正确的答案可能在下面
class Solution:
def myPow(self, x: float, n: int) -> float:
if n == 0:
return 1
if n > 0:
return self.myPow(x * x, int(n / 2)) * ([1, x][n % 2])
else:
return self.myPow(x * x, int(n / 2)) * ([1, 1/x][n % 2])