题目:
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
解析:
这道题应该很多人都做过,刚开始学编程都会遇到这道题,这道题跟爬楼梯,青蛙跳台阶特别相似,不过就是初始条件的不同罢了。这道题有三种方法可以解决,最常用的传统方法-迭代法,根据这个数列的规律去解决,其次是使用递归来解决,在递归的基础上,用动态规划的方,解决递归重复计算的问题。
第一种:迭代法,根据斐波那契数列的规律,从第3项开始,每一个项都等于前两项的和,然后进行遍历相加赋值即可。
# 第一种,根据斐波那契数列的规律,直接遍历返回即可。(这是从小到大,自底向上)(迭代法)
def fib(n: int) -> int:
f0 = 0
f1 = 1
while n > 0:
# f0代表前一项,f1代表后一项(后一项总是等于前两项的和)
f0, f1 = f1, f0 + f1 # 因为fib数列除了1,2项之外,之后都是前两项的和,所以每次遍历,都将新的结果赋值给之前。
# 保留最新项的结果,最后返回要获取的第几项结果
n -= 1
return f0 % int(1e9 + 7)
第二种:采用递归的方法,自顶向下,从当前数一直递归到终止条件,然后回溯相加即可。
#第二种,递归(自顶向下,然后回溯即可):有两个终止条件,n==0,f0=0,n==1,f1=1
def fib2(n: int) -> int:
if n==0:
f0 = 0
return f0
elif n==1:
f1 = 1
return f1
# 递归条件:F(N) = F(N - 1) + F(N - 2):
# 把 f(n)问题的计算拆分成 f(n-1)和 f(n-2)两个子问题的计算,并递归,
# 以 f(0)和 f(1)为终止条件。
return (fib2(n-1)+fib2(n-2))%int(1e9 + 7)
第三种方法:动态规划法,因为递归进行了重复计算,在递归的过程中,其中的某一项需要计算多次(例如 f(n) 和 f(n - 1) 两者向下递归需要各自计算 f(n - 2)的值。),那么我们可以将中间结果保存起来,当再次计算时只需要拿出来即可。
#第三种,动态规划:以斐波那契数列性质 f(n + 1) = f(n) + f(n - 1)为转移方程。(爬楼梯翻版)
#解决了递归大量重复的计算
def fib3(n: int) -> int:
dp = [0]*(n+1) #动态规划网格
if n==0:
return 0
#动态规划初始条件
dp[0] = 0
dp[1] = 1
for i in range(2,n+1):
dp[i] = dp[i-1]+dp[i-2] #状态转移方程
return dp[-1] #返回最终的结果
执行结果:
输入10