剑指 Offer 10- I. 斐波那契数列
-
题目
写一个函数,输入
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
-
难度:简单
-
分类:了解
-
题解
这道题是很经典的递归题,也是大家入门递归会经常看见的一道题,那么这道题我们就用动态规划做。动态规划对空间复杂度消耗高,但是其运算速度是非常快的,代码如下:
public int fib(int n) { if(n<2) { return n; } int []nums=new int [n+1]; nums[0]=0; nums[1]=1; for(int i=2;i<n+1;i++) { nums[i]=(nums[i-1]+nums[i-2])%1000000007; } return nums[n]; }
那么按照以上方式提交的结果则是:
-
递归
前面都提到了这是一道典型的递归题,那么这里我们就要详细讲一讲递归了。对于递归来说,就是不断地调用直接来达到目的的方法。那么递归函数包含三个反面:退出条件,本轮函数需要干什么,返回什么。(为了方便大家理解,大家可以参照下面的代码理解,但是该代码并不能通过本题,因为会超时,只是为了方便大家理解)
代码如下:
public int fib(int n) { //退出条件 if(n==0||n==1) { return n; } //本轮操作 int num=fib(n-1)+fib(n-2); //返回什么 return num; }
在本次题目中,我们需要不断计算前两次的值,一直计算到 n = 0 和 n = 1 n=0和n=1 n=0和n=1的情况,所以说,函数在这个条件下就停止了,所以这个就是退出条件,这个时候返回的值是确定的值,不能再是与自己函数相关的值了,那样递归不会结束,也不会有出口,直接导致函数结束不了。
接下来,我们看本轮需要干什么,当前我们得到的数是n,那么我们知道我们需要返回的数值是输入为 n − 1 和 n − 2 n-1和n-2 n−1和n−2返回数值的和,于是本轮我们需要计算这个数值。
最后,我们需要返回什么,我们需要将我们计算的数值进行返回。
以上就是解本题的步骤,递归是一个很好用的工具,大家需要多刷些递归的题目,来进行理解。
那么本题其实并不适用于直接用递归来解决的原因是会出现重复的计算,那么可以通过下面这个图片来理解:
我们可以看见它出现了重复运算的情况,那么这个时候我们就要用到动态规划的数组,对已经计算的值进行储存,这样就不需要再重复计算了。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。