面试题16 数值的整数次方(Python3) 递归+分治

实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

说明:

  • -100.0 < x < 100.0
  • n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1]

先用自带函数试一下:

class Solution:
    def myPow(self, x: float, n: int) -> float:
        return x**n

果然很高效

 

方法1 直接计算O(n)

思路

因为n是整数,故对n分情况讨论:

当n=0时,直接返回1即可;

当n>0时,则令x与x相乘(n-1)次即可;

当n<0时,则令1与x相除((-n)-1)次即可。

代码

class Solution:
    def myPow(self, x: float, n: int) -> float:
        power = 1
        if x == 0:
            if n != 0:
                return 0
            else:
                return 1
        if n==0:
            return 1
        elif n > 0:
            for i in range(n):
                power = power * x
            return power
        elif n < 0:
            for i in range(-n):
                power = power / x
            return power

结果超出时间限制

 

在该算法中,时间复杂度为O(n).

 

方法2 二分法O(log2(n))

思路

有了上面的失败经验,这道题还是需要技巧的。

首先,n=0和n<0都可以转换为n>0,所以下面就针对n>0进行讨论:

如果像方法1那样计算x*x*x...*x是要计算n次的,所以复杂度为O(n);

如果能够改为计算(x^2)*(x^2)*(x^2)*(x^2)...*(x^2),则复杂度就会变成O(n/2);

 

如果能够利用分治思想,通过递归的方法,即每次都能将x的幂除以2,则复杂度就会成为log2(n)

具体代码如下

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n>0:
            mod2 = n %2
            if mod2 == 0:
                npower2 = x*x
                return self.myPow(npower2,n//2)
            elif mod2 == 1:
                npower2 = x*x
                return self.myPow(npower2,n//2)*x
        elif n<0:
            n = -n
            return 1 / self.myPow(x,n)
        else:
            return 1

结果

此时时间复杂度为O(log2(n)),不再超时。

 

方法3 "三分法"O(log3(n))

类似的我们还可以对其进行三分,每次迭代n都除以3,从而降低复杂度

 

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n>0:
            mod3 = n %3
            if mod3 == 0:
                npower3 = x*x*x
                return self.myPow(npower3,n//3)
            elif mod3 == 1:
                npower3 = x*x*x
                return self.myPow(npower3,n//3)*x
            elif mod3 == 2:
                npower3 = x*x*x
                return self.myPow(npower3,n//3)*x*x
        elif n<0:
            n = -n
            return 1 / self.myPow(x,n)
        else:
            return 1

时间复杂度O(log3(n)),因此速度更快(其实只是理论速度更快,实际测试过程中并不一定)

总结

递归+分治的思想可以用来降低时间复杂度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值