leetcode50.Pow(x,n)

题目:

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例:

输入:x = 2.00000, n = 10
输出:1024.00000

输入:x = 2.00000, n = -2
输出:0.25000
解释: 2 − 2 = 1 / ( 2 × 2 ) = 1 / 4 = 0.25 2^{-2} = 1/(2×2) = 1/4 = 0.25 22=1/(2×2)=1/4=0.25

思路:

方法1,常规操作,先判断特殊情况,再一个一个乘,如果是小于0就一个一个除,但是这样会执行出错的。
方法2,普通的递归,会超时。

这里就是先判断特殊情况,然后就返回当前幂除以2,调用原函数乘以剩下的部分同样调用原函数,直到幂次为1返回值,但是这样计算有很多重复的部分,每次都要调用两次原函数,比如计算某个值,计算很多次相同的结果。

方法3,优化递归

减少重复的计算,并且每次只调用一次函数,这里先判断特殊情况,然后当为偶数时,比如为4的时候,就是调用x的平方的平方,然后再调用x的四次方的一次方,就可以返回x的四次方,这里是先计算x的平方,再计算x的四次方,如果是奇数,就先按照这个数减1的偶数计算,最后再乘以x,这样减少了重复,提高了运算效率。

方法4

位运算的方法,将十进制数转化为二进制数,比如10写成1010,幂次就可以写成2的三次方加2的一次方,原来的x的十次方就可以转化为x的8次方(2的三次方)乘以x的2次方(2的1次方),就是我们在最终的计算公式中保留的是二进制数中是1的位置上结果,比如1010,从右往左,第一位是1,而且是最高位,保留2的三次方,第三位是1,保留2的一次方。代码思路是从右往左取的,最低位如果是1就是乘以2的0次方,就是保留x本身乘进最后的结果里。

class Solution(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        # ans = 1
        # if n == 0:
        #     return ans
        # for i in range(abs(n)):
        #     if n < 0:
        #         ans /= x
        #     if n > 0:
        #         ans *= x
        # return ans
        #常规操作,执行出错,嗯嗯嗯
        # 普通递归,会超出时间限制,因为这个过程里每一次递归都要调用两次函数,并且两个函数中有很多重复计算,比如计算x的5次方,中间计算好几次x的平方,x的一次方。
        # if n == 0:
        #     return 1
        # if n == 1:
        #     return x
        # if n < 0:
        #     return 1/self.myPow(x,-n)
        # return self.myPow(x,n//2) * self.myPow(x,n-n//2)
        # 优化递归,如果减少重复的运算,并且每一次递归只调用一次函数
        # if n == 0:
        #     return 1
        # if n == 1:
        #     return x
        # if n < 0:
        #     return 1/self.myPow(x,-n)#先按照正的计算,再取其倒数即可
        # return self.myPow(x * x,n//2) if n%2 == 0 else x * self.myPow(x,n-1)
        # 这样就终于AC了
        #不用递归的方法,用位运算的方法
        # if n == 0:
        #     return 1
        # if n == 1:
        #     return x
        # 以上两种情况都包括了
        if n < 0:
            return 1/self.myPow(x,-n)
        res = 1
        x_o = x 
        while n > 0:
            if n % 2 == 1:#取当前的最低位
                res = res * x_o
            x_o *= x_o#不断更新,当前位置为1时,要乘以的x的次幂,分别是x的1次方,x的2,x的4,x的8次方等等,直到跳出循环
            n //= 2#地板除,十进制转二进制的过程
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值