每次想从头学做算法题,就逃不开斐波那契额序列(Fibonacci)和a的n次方问题(an)。感觉着两道题是所有算法的入门基础,但其实这两道题有很多的门路,其实还是挺不容易的。话不多说a的n方问题很容易理解这里就不在介绍题型了,求an
很容易理解就是for
循环对a
的连乘,直接上代码。
def pow(a, n):
if n < 0:
if a == 0: return 0.0
return 1.0 / pow(a, -n)
res = 1
for i in range(n):
res *= a
return res
但是这个实现方式复杂度是要爆炸的O(n)
。
你TM仿佛在侮辱我的智商!!!
那么我们如何改进呢?其实就是顺着思路往下想,一个一个乘复杂度过高,那么我们能不能跨步的去乘呢?
我觉得这道题是引入分治思想最为合适的一道入门题。
an分治的算法思路就是:
优化算法思路是有了,但是实现分治的方式也有2种当然两种时间复杂度都是O(logn)
:
位运算代码
# 位运算
def pow(a, n):
if n < 0:
if a == 0: return 0.0
return 1.0 / pow(a, -n)
res, tmp = 1, a
while n:
if n & 1:
res *= tmp
n >>= 1
tmp *= tmp
return res
下面是递归代码
# 递归实现
def pow(a, n):
if n < 0:
if a == 0: return 0.0
return 1.0 / pow(a, -n)
if n == 0: return 1
r = pow(a, n // 2)
return r * r * a if n & 1 else r * r
这个题在计算方面其实并不是很难,难就难在一开始的条件判断n会不会出现小于0的数,a是否等于0,所以在实现的过程中需要非常的细心。