python输出n的32次方,面试问题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

ed2c6089ee6d082150bc5b0a87ae3a1d.png

果然很高效

方法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

结果超出时间限制

bd7440de2df5ed2c602a92a77deaf0a7.png

在该算法中,时间复杂度为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)),不再超时。

35fbd7bb9a801153d421fe6f5c2c605f.png

方法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

71b72b1fa53224f3bd9fb16a59f65391.png

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

总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值