Leetcode 50:Pow(x, 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/2^2 = 1/4 = 0.25

说明:

  • -100.0 < x < 100.0
  • n 是 32 位有符号整数,其数值范围是 [ − 2 31 −2^{31} 231, 2 31 − 1 2^{31} − 1 2311] 。

解题思路

我们首先想到的做法就是区分n是正数还是负数。如果是正数的话,我们就不断的乘x。如果是负数的话,我们就不断的除x。乘和除的次数都是n即可。

class Solution:
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        res = 1.0
        for _ in range(abs(n)):
            if n > 0:
                res *= x
            else:
                res /= x
        return res

很显然问题没这么简单,我们提交结果超时了。当n非常大的时候我们乘积的次数太多了。这个问题我们很容易联想到之前的一个问题Leetcode 29:两数相除(超详细的解法!!!)。我们可以使用相同的思路,通过增量式的思路来处理。对于输入x=3n=1000来说,可以变为

  • 3 1000 = 3 2 9 ∗ 3 2 8 ∗ 3 2 7 ∗ 3 2 6 ∗ 3 2 5 ∗ 3 2 3 3^{1000} = 3^{2^9}*3^{2^8}*3^{2^7}*3^{2^6}*3^{2^5}*3^{2^3} 31000=329328327326325323

现在我们的问题就变成了编程去实现这样的拆解。我们首先想到的做法就是先找到小于10002的最大幂指数512,接着我们继续找小于1000-512=4882的最大幂指数256,以此类推。所以可以想到的思路就是建立一个32维的数组空间存放2的幂指数。

其实还有一种更好的办法,如果你观察到这样的规律话

Leetcode 50:Pow(x, n)(超详细的解法!!!)_第1张图片

观察每次数字是不是奇数,如果是奇数的话我们保留对应的2的幂次即可。

class Solution:
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        m = -n if n < 0 else n
        p, q = 1, x
        while m > 0:
            if (m & 1) == 1:
                p *= q
            m //= 2
            q *= q
            
        return 1/p if n < 0 else p

对于这个问题通过递归来处理思路会更加清晰,我们定义函数 f ( x , n ) f(x,n) f(x,n)返回 x n x^n xn值,那么

  • f ( x , n ) = f ( x , n / 2 ) 2   ( n   i s   e v e n ) f(x,n)=f(x,n/2)^2\ (n\ is\ even) f(x,n)=f(x,n/2)2 (n is even)
  • f ( x , n ) = f ( x , n / 2 ) 2 ∗ x   ( n   i s   o d d ) f(x,n)=f(x,n/2)^2*x\ (n\ is\ odd) f(x,n)=f(x,n/2)2x (n is odd)

我们定义的上述函数只能处理n为正数的情况。对于边界问题,我们要分开考虑

  • n = 0 n=0 n=0
  • n = 1 n=1 n=1
  • n < 0 n<0 n<0
class Solution:
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if n == 0:
            return 1.0
        
        if n == 1:
            return x
        
        m = n // 2
        if n < 0:
            m = -m
            x = 1/x
            
        res = self.myPow(x, m)
        
        if (n & 1) == 0:
            return res * res
        return res * res * x

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)