引言(关于递归)
-
之前和同学讨论的时候,发现很多题目类型像动态规划(dp)、回溯、链表,他们的思维想和解决方法差别都很大,但是好像底层都可以用递归实现的
-
学习动态规划的时候,所有的动态规划的题目,都可以用递归和非递归的方式来实现,为什么?
-
几个月前刚接触算法时,接触的就是排序,排序的最优子结构和最优子算法使我考虑是否可以用递归去解决
-
在B站上看到一个视频,说的是程序员如何用非递归的方式解决问题
递归是什么?什么叫“如何用非递归的方式解决问题”?
我个人认为
-
算法题的程序无非两种形式:递归和非递归
-
不同于网上和大多数书上的说法,我认为递归不是一种算法,而是一种思想(一种化归的思想),一种编程方式(即自我调用的编程方式)
-
我认为只要存在自我调用(不管是函数的做调用,还是数组的自我调用),在编程形式上都可以称为递归
-
递归使用特定情景作为终止条件(更简单,更直观化,更易于理解的条件)代替循环的终止条件
-
递归的三要素是:递归函数(或数组之类)定义、结束条件和递推关系(等价关系) 那么可不可以反过来理解,只要能找到相应的递推(或递归)关系,找到终止条件,就可以用递归来实现呢
接下来是对上述论述的逐一解释
-
这个是因为我把递归的外延扩大了,在集合上递归和非递归是对立互补的(但其实仅仅是我的一个个人理解和假说而已,大家不必当真(雾)
-
这里我们需要讲一下计算机思维和计算机拓扑(个人理解,等喷) 计算机擅长解决大量的重复性计算的问题[其实它也只能进行简单的且大量的数字运算和逻辑运算(本质上还是运算,所以叫计算机)]编程者要做的是把具体问题转换成可执行的,能得到结果的程序。而我们要干的事情就是把重复性的事情用简洁的语言表达出来(这我理解为计算机思维)在把握和理解问题的时候,我们需要具有抽象概括出具体事物的同一性质的能力(这我理解为计算机拓扑)。所以其实本质上我们要干的事情就是化归,由大化小,由小得大。
- 纯属个人理解,等喷
- 字面意思,等喷
- 很多时候我们说动态规划问题非常难理解,但如果在学习一个新的章节的时候,我们不把这种早已归类好的算法当成一个全新的东西去学,这个是用递归的结构去理解它(以动态规划问题为例,动态规划问题分四步:确定dp数组含义及下标含义、确定递推公式、初始化dp数组、确定遍历顺序。那这里情商很明显的看出,动态规划问题不过只是多了一个初始化数组〈其实这个可以理解为最后一次的返回值〉完全可以用递归的方式来写),你会觉得,诶,这不完全就是一回事吗?
总结
我写这篇文章只是想记录在蓝桥杯的备赛过程中,关于递归的一些个人理解。
其实很多问题,用非递归的方式就可以做了,包括用记忆化数组去记录计算结果等优化方式。但我想说的是,算法书上的绝大多数题型和算法,都是可以用递归的方式去理解的。 学习的时候就直接这么理解的好处,就是它方便你直接进行编程。很多东西,像dfs,bfs,都是说起来一套做起来一套的(你如果光看他的文字论述,听上去是很好理解,但想破脑袋也想不到怎么去实现)。所以我觉得我们学习的时候只需要先去弄清楚这个算法的思想是什么,它能解决什么问题,然后再背例题(这个我觉得是不可避免的,总归要背点题的,就像程序的基本语言基本代码,你问我为什么这么写,我也不知道,我只能告诉你,你必须得背出来才能继续学),最后再靠刷题巩固。
后记(扯皮,可跳过)
本人目前大一,写这些东西只是为了记录一下个人的理解。非常希望有大佬能看到这篇文章,并且给予批评和指正。