您的位置:首页 > 理论基础 > 数据结构算法

算法数据结构面试分享(九)从斐波那契数列初识递归

2018-03-26 19:30 267 查看

从斐波那契数列初识递归

斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368.. 今天我们来一起回顾一下这个数列,重新认识一下递归的原理。
大家还记得我们的课本上讲递归的时候,先引入的是它的算法定义,然后带大家去编码的对吧?说到这里不得不吐槽下中国的教育改变了我们思考问题的方法,以致于我们在处理一个真正问题的时候很难指出来这是一个可以用递归解决的问题。我这里先留一道题哈,下节课我们一起来分析一下,有N个台阶,假设我们每次抬脚,可以选择走一个台阶,也可以选择走两个台阶,那么请问,完成这N个台阶有多少种走法?言归正传,我们继续说递归(今天我们的思路和之前其他的算法题会有所区别)。
一、什么样的问题可以用递归?
    所有能够用递归解决的问题都会满足如下几个条件:

问题是可以分解的,大问题可以划分为若干子问题
子问题在某种程度上还是原来的问题,根本的性质是一样的
子问题的规模比原问题小
子问题解决了,我们就能解决更大规模的问题
子问题无限分解也是有终止条件的,而且终止条件满足时,问题的解是显而易见的         
那我们一块再来看下斐波那契数列,是不是满足这样的规律。
F(n) = F(n-1) + F(n-2) ; n > 2
F(n) = 1; n =1,2
F(n) 能划分为小问题 F(n-1) 和 F(n-2), 而 F(n-1) = F(n-2) + F(n-3), 是不是 F(n-2), F(n-3) 解决了才能求出 F(n-1), 进而求出F(n)呢? 他们的问题都是F问题,而且,F(1)=1, F(2) = 1; 是不是F问题存在终结条件呢?
二、如何用递归解决问题?
    经过分析之后我们断定这是一个递归问题,我们需要找的就是递归公式了。找到递归公式之后我们需要找到终结条件和它的值。 从上面的例子中,如果给了递归公式了,我觉得这道题就没有什么意思了。大家可以等我下一篇文章,我们会从问题出发。上面的数列当中,我们会发现第一个和第二数都是一个特例,之后的数等于前面两个数之和。

三、递归的真正原理和替代算法是什么
    我们再看F(n) = F(n-1) + F(n-2), 大家知道F(100)的求解过程吗?这里面存在两个过程,递推和回溯。要求F(100) 我们先要求F(99), F(98), 而 F(98)先要求出F(97), F(96), 知道F(1), F(2);

    现在我们求出了F(1), F(2), 我们再回去求F(3), 进而F(4), 一直到F(100). 

    从上面的求解过程中,大家发现了在递推的过程中,我们把子问题是不是都依次入栈了,知道我们求出F(1,2)我们再将问题依次出栈,之后最后一个问题F(100). 所以大家能够发现,递归的本质就是入栈、出栈的问题,所以递归的复杂度会很高。同时,我们能够用栈来优化递归。
四、递归的代码模式递归的代码中包含两个重要部分, 终止条件时直接返回,否则缩减问题规模调用它本身。
public static int F(int n)
{
if (n > 0)
{
if (n == 1 || n == 2) return 1;

else
{
return F(n - 1) + F(n - 2);
}
}
else
{
throw new ArgumentException("The N should not a negative number.");
}
}大家如果发现以上算法有什么问题,欢迎大家交流哈。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐