对递推和递归的理解
1.此问题能否用递推解决
我们以斐波拉契数列问题为例进行阐述,斐波拉契数列为0、1、1、2、3、5、8、13、21、…表现斐波拉契数列为瘦柱状图的形式,如下
我们现在所要解决的问题是求取第n个位置的数值,下面我们正式开始考虑能否用递推解决这个问题(关于递推和递归的区别,将会在下文阐述):
我们考察3号位置,我们发现3号位置的值依赖于1号位置和2号位置,即在1号位置的值和2号位置的值的基础上,我们再进行一些(一个)操作就可以得到3号位置的值。在本例中,这个操作为加法运算。
我们再考察4号位置,同样我们发现4号位置的值依赖于2号位置和3号位置。
我们现在可以建立一种递推关系:F(n) = F(n-2) + F(n-1)。
至此,我们可以抽象出一种模式,这种模式告诉我们:待求位置的值仅仅依赖于前两个位置的值,再进行加法操作即可。换句话说,如果我们知道前两个位置的值,第三个位置的值就可以得到。
是否在起点的临近区间内存在这种模式决定了这个问题能否用递推解决。这里的起点和数学归纳法中的起点的含义一样。
所以本问题可以用递推解决。
2.将这种模式应用于高位
观察上图,我们现在想要求取n号位置的值,根据这种模式,我们只需要知道n-2号位置和n-3号位置的值即可。这样我们就把一个规模大的问题转化成规模小的问题。然后一直向问题规模变小的方向发展即可。
3.总结
总结一下刚才的一系列过程:首先在低位发现一种模式,这种模式可以将规模大的问题转化为规模小的问题。然后将这种模式应用于高位。最后编码。数学归纳法的思想贯穿整个分析过程。
4.将问题的范围从求取一个值扩大到求取一系列操作
下面我们以汉诺塔问题进行阐述,读到这里,应该很累了,哈哈,那我就打个鸡血,下面的文字将会教你在一分钟内解决汉诺塔问题,哈哈,激动吧。首先,我们在低位进行探索,看能否抽象出一种模式。
我们考察三个盘子的情况,下图说明如何移动。
首先将最上面的两个盘子移动到第2根柱子(这是一系列操作),然后将最大的盘子移动到第3根柱子,最后再将第2根柱子上的两个盘子移动到第3根柱子(与上面相同的一系列操作)。至于如何两个盘子从一个第1根柱子移到第2根柱子(借助第3根柱子),以及如何将两个盘子从第2根柱子移动到第3根柱子(借助第1根柱子)我们不必关心,我们只要知道抽象出一种模式。这种模式告诉我们想移动3个盘子,只要知道怎样移动2个盘子。
下面我们将这种模式应用于高位,现在想要移动n个盘子,下面的图片讲述了如何将其转化成移动n-1个盘子
所以我们现在只需要记录下3个盘子移动,然后就可以递推出4个盘子如何移动,5个盘子,…
至此n个盘子如何从一个柱子移动到另一个柱子已经解决。哈哈,应该差不多一分钟。
5.递推和递归的区别
在这里我想谈谈自己对递推和递归的理解,自己感悟,并没有权威参考。
递推是一种关系,由小推大。将递推这种关系用某种计算机语言实现出来为递归。
6.最后
本文到此就结束了,哈哈,其实关于递推还有一些工作需要做,对递推关系的具体编码,分析递归函数的运行时间,递归栈,涉及到的分治技术等等,本文的主要目标是让我们更好的理解递推,更好的认识递推。有了这些认识和理解后,我相信以后的递推之路可以平坦些。在此感谢周兆熊学长(百度,“周兆熊 csdn”)没有他的监督,我也不会很快完成这篇markdown博文。路漫漫其修远兮,吾们将上下而求索,欢迎志同道合的人一起加入我们的小而精悍的微信群,哈哈。