斐波那契数是一个很基础的数学问题,不过看到leetcode上面采用了好几种解法,还是很有趣的
这里也学习了一下,【递归】跟【动态规划】到底有什么区别。
思路上其实都是通过两个数字反复相加迭代推导出最后的目标n,但递归方法需要占用空间内存大(从后往前推导),动态规划只需要两个动态变化存储的空间位即可(从前往后动态储存)。
关于递归和动态规划说明如下,解释的很不错:看动画轻松理解「递归」与「动态规划」(完整版) - 五分钟学算法 - 博客园 (cnblogs.com)https://www.cnblogs.com/fivestudy/p/10217887.html以及动态规划类题型求解,有通用公式:
代码:
'''
#动态规划,自己写的比较生硬
class Solution:
def fib(self, n):
num=1
add1=0
add2=1
#for i in range(n):
if n==0:
return 0
if n<=2:
return 1
else:
for i in range(n-2):
add1=num#储存更新前的num数据
num+=add2#累加
add2=add1#储存上一轮运行更新后的数据
return num
'''
#当大数迭代计算时,需要对结果取模%10
#法1:动态规划,干净code
#时间复杂度:O(n),n个节点(循环) 空间复杂度:O(1)。
class Solution:
def fib(self,n):
if n<2:
return n
#设置斐波那契数列的初始值,至少有三个数字F(n)=F(n-1)+F(n-2)。F(0)=0,F(1)=1,F(2)=1+0 n>1
p,q,r = 0,1,1
#i从0开始,因此初始值在最前面多加一个F(0_start)=0
for i in range(n):
p,q = q,r
r=p+q
return p
'''#官方code:
class Solution:
def fib(self, n: int) -> int:
if n < 2:
return n
p, q, r = 0, 0, 1
for i in range(2, n + 1):
p, q = q, r
r = p + q
return r
'''
'''
#法2:通项公式(数学求解)
#斐波那契数 F(n)F(n) 是齐次线性递推,根据递推方程 F(n)=F(n-1)+F(n-2)F(n)=F(n−1)+F(n−2),可以写出其的特征方程:
x^2=x+1,解得x1,x2,写出数学通解(具体见官方https://leetcode-cn.com/problems/fibonacci-number/solution/fei-bo-na-qi-shu-by-leetcode-solution-o4ze/)
class Solution:
def fib(self, n):
sqrt5 = 5**0.5
fibN = ((1 + sqrt5) / 2) ** n - ((1 - sqrt5) / 2) ** n
return round(fibN / sqrt5)
#法3:递归(最容易想到,最占用内存)
#空间复杂度o(2^n),逆推结果需储存;时间复杂度O(n)
class Solution:
def fib(self, n):
if n<2:
return n
else:
#类内函数调用需用self.function()
return self.fib(n - 1)+self.fib(n - 2)
'''
if __name__=='__main__':
n=4
a=Solution()
print(a.fib(n))
第 N 个泰波那契数同理,也用到了动态规划:
代码如下:
class Solution:
def tribonacci(self, n: int) -> int:
if n==0:
return 0
if n==1:
return 1
#if n==3:
# return 2
a,b,c,d=0,0,1,1
for i in range(n-2):
a,b,c=b,c,d
d=a+b+c
return(d)