50. Pow(x, n)
问题链接
https://leetcode.cn/problems/powx-n/description/
解题思路
这个题目具有缩小规模的潜质,所以可以用递归来进行解决。
为啥呢?因为幂本质上就是乘法。 2的3次幂,就是2*2*2。所以,我们要做的就是减少乘法的次数。
比如2的10次幂,它其实等于2的5次幂相乘。
2的5次幂,相当于2的2次幂相乘,再乘以一个底数。
2的2次幂,就等于2和2相乘。
2的1次幂,就相当于2和2的0次幂相乘。
这么算起来的话,我们把2的10次幂,10次乘法,缩减到了4次。没想到吧递归竟然有效率高的时候。
等等,那幂为负数咋办?好办,根据数学公式, 2的-2次幂,等于1除以(2的2次幂)。
既然幂有正负之分,那我们就不用题目给出的函数了,可以另外设置一个dfs。这样的话避免了在递归函数中进行正负号的处理,返回值自然就是幂运算的结果。
然后我们设计本层需要做什么。首先我们计算下一层的幂结果,这很重要,这相当于我们有了一个缓存,而不需要计算两次。
如果n为偶数,那下一层的幂结果的平方肯定为n。如果n为奇数,那下一层的幂的结果的平方肯定是n-1。 那我们怎么拼接本层结果呢?
本层结果,如果n是偶数的话,直接将下一层幂的结果相乘即可。
如果n是奇数的话,将下一层幂的结果相乘,还要乘以一个底数x,这样才可以。
最后,我们设计递归的出口。 n不断的除以2,总有到0的时候。任何数的0次幂都是0,所以直接返回1即可。
代码
class Solution: def myPow(self, x: float, n: int) -> float: def dfs(N): if N == 0: return 1 child_res = dfs(N//2) return child_res*child_res if N%2 == 0 else child_res*child_res*x return dfs(n) if n>0 else 1/dfs(-n)
另一个实现:
class Solution: def myPow(self, x: float, n: int) -> float: if x == 0: return 0 if n == 0: return 1 if n < 0: return 1/self.myPow(x, -n) tmp = self.myPow(x, n//2) if n % 2 != 0: tmp = tmp * tmp * x else: tmp = tmp * tmp return tmp