前言:本文章为最后一部分,将直接讲述如何根据斐波那契数这一问题运用递归,若有对递归定义以及递归的过程不够理解的同学请看前一章节后再看本文章。
问题描述:
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。
根据正常思路流程来,我们先分析问题,如关于该问题第一部分(前面文章)所讲解那样,我们知道这主要是一个递推式,我们要利用现有信息F(0)与F(1)去推未知信息F(n),这中间过程会存在重复同类问题,整体符合递归的定义:一种通过重复将问题分解为同类的子问题而解决问题的方法。如此,我们会想到用递归来写这种存在同类循环的问题。初学者可将其精简为出现循环重复就考虑递归。
接下来我们考虑递归的可行性,在上篇文章我们讲述了递归的定义的重点分为两点,1、分解为同类子问题2、重复分解子问题。 首先对于第一点定义的要求,这题中同类子问题就没有那么容易看出,中间的等式为F(n)=F(n-1)+F(n-2),由于问题的规模降低,首先可知这是分解过程。同类问题只通过F(n)=F(n-1)+F(n-2)是得不出的,因为一个是函数,另一个是函数的加法,我们需要再次分解等式。
F(n) = F(n-1) + F(n-2)
F(n-1) = F(n-2) + F(n-3)
将等式再次分解后,可以看出两等式的后半部分都是同类问题,从而得出F(n)与F(n-1)是同类问题(这个好像一目了然)。
可能会有读者觉得F(n)与F(n-1)是同类问题,就如上篇文章我所说那样:它们都是同一个函数了!还不同类!
其实可能会存在特殊情况,例如:F(3)=F(2)=1,F(0)=0,F(2)与F(1)并不是同类问题,因为它们直接并不存在等式使它们具有关联性。
对于第二点要求,重复分解。如同一个人走路,我们从F(0)、F(1)这两个落脚点开始,我们向F(n-1)+F(n-2)方向行走,第一次踩到F(2),再F(3),如此可重复走到F(n)。既然可以走过去,同理我们也可以走回来,从F(n)一步一步分解最后成为F(0)、F(1)。
符合定义要求,可以用递归写这题。请你抓住“走路方向”和“落脚点”再次写一下这题。
class Solution {
public:
int fib(int n) {
if(n == 0)
return 0; //最后落脚点
else if(n == 1)
return 1; //最后落脚点
else
return fib(n-1) + fib(n-2); //分解方向
}
};
递归和循环其实是一样的,不同的是递归是一个方程,而循环是等式。在方程中,我们可以用x、y、z代替未知数,我们可以直接利用我们目前并不知道的信息运算下去直到遇到已知信息再返回一次全部解答,这个过程难道不就是解方程式嘛。而在循环中,我们每次都是利用已有信息再去推未知信息。如果还不太理解那就多解几个方程式吧,获取到“可知的”未知数的魅力!
闲聊:真心希望能帮到和我当初学习时一样困惑于书本和答案的初学者,如果你有任何不理解之处,期待你评论提问。
文章不足之处,不方便理解处待指正。
力扣题目链接:https://leetcode.cn/problems/fibonacci-number/