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

 

posted @ 2023-01-06 11:20  BJFU-VTH  阅读(17)  评论(0编辑  收藏  举报