学算法的时候,递归确实是最绕的,这个东西怎么说呢,思路比较反自然思维....
为啥说它反思维呢:自己调自己,而因为你在调用自己的时候只用了一个Fn-1,但事实上这个Fn-1代表了超级多个Fn-2Fn-3......,这是最让人思维感到难受的地方,但是用久了发现:真香
你只需要明白一个思想,就是面对一个看起来超级复杂难以下手的问题,目标是把它转化为一个简单的靠直觉就可以解决的问题
递归算法可以抽象为一个模版———
递归公式+递归边界=递归算法,然后我通过一个小例子来解释一下
比如排序问题,让你从大到小排100个数,你是不是会感到很头大,但是让你排两个数呢?是不是看哪个最大就行了,把它放在左边,就排好了
而递归就是把大问题抽象为极其简单的小问题,然后找到小问题和小问题之间如何组合还原为“大问题”
第1步,就像刚才的100个数,我是不是可以减小一下工作量,就是大的50个在左边,小的50个在右边,这样把左边和右边合在一起不就是咱们想要的排序吗
第2步,想要解决这个子问题,发现50个数排好还是挺头大的,那咱再减小一下工作量,对于大的50个:咱把这里面25个最大的放在左边,小的25个放在右面
........几个1、2步骤以后......
第n步,有2个数,对于这两个数,咱们终于发现,不头大了!!!把大数放在左面,把小数放在右面,这不就OK了?
聪明的你一定会发现,每一步咱们都在做相同的事情———把大的放在左面,把小的放在右面,然后合并左右(当然实际合并是用一个双指针实现的)
好了这就是一个简单例子(具体实现就是“归并排序”,能在O(N•LogN)内解决排序问题),现在咱们来总结一下这个例子
递归边界:
当一组里只有两个数的时候,也就是我们可以秒杀得出答案的时候
递归公式(步骤):
1.把现在要解决的数列分成两组数量小数列大的在左,小的在右(因为目标是从大到小)
这个递归思想呢,其实就是层层剥开再细化执行,就跟总领导把大任务细化成各种方面的小任务,分配给不同部门的领导,不同部门的领导再分配给小职员 一个道理
就是将规模为n的问题转化规模为n-1的小问题
回到你提的问题汉诺塔问题,要解决N层汉诺塔问题,你要怎么做?
首先什么最简单?只有3层的时候想必大家都会做,而其实通过3层和4层的详细解法我们会发现一个规律:想要把n个圆盘转移,我们先得把上面N-1个圆盘都给清理干净才能动最底下的盘子,所以Here the thing is(规律)
1.首先,将n-1个圆盘从“起始柱”柱移到“中转”柱(解出n-1层)
2.后,将最大的圆盘从“起始柱”柱移到“目标柱”
3.后,将n-1个圆盘从“中转”柱移到“目标”柱(解出n-1层)
那么道理懂了,那么N层汉诺塔问题的具体步骤是啥(哪个盘子从哪个柱子转移到哪根柱子)
不用想了(狗头),肯定麻烦的要死啊,但我们可以简化一下,A柱到B柱B柱到C柱......等等一系列操作通通叫做“N-1层汉诺塔问题解决步骤”,然后遇到“N-1”层的时候可以把剩下的步骤叫做“N-2”层.......等等
对于每一层我们都很简单,都是三步走,最后整个事情也就解决了
具体实现就不说了,思想get到就可以了,理解就是分分钟的事情,加油!
递归模块
对于递归有没有什么好的理解方法?
用数学代入法来理解就好。
假设我们用递归来算阶乘 f(n)
f = n =>
n === 1 ? 1
: n * f(n-1)
f 里面用到了 f,怎么理解呢?
很简单,把式子展开即可:
看到递归了吗?
先递进,再回归——这就是「递归」。
以上是 SICP 原文(有删改)。