递归
如何理解
举个生活中的例子:当你想要在字典中查找到某个字时,首先是在索引中找这个字首字母,其次找到完整音节,再在相同音节中找到自己所要查询的字,最终得到目标字页码,这就是递归。
递归就是自己调用自己,把大问题拆解成同类型的小问题,直到小问题可以完全解决,再从最底层的解开始回溯合并得到大问题的解。
三个要点
1.终止条件:告诉递归什么时候停止,避免进入无限循环(找到目标字,查字典结束)
2.拆解问题:将大问题拆解成同类型小问题(查 ‘厨’ -> 查 ‘C’ -> ‘chu’ -> ‘厨’)
3.回溯合并答案:将各步骤结果串联(return 索引查询结果+音节查询结果+目标字查询结果)
简单示例
在我们刚开始学递归,接触到的代码例题一定是求n的阶乘,我们来看一下是否是上述思想。
// 求n的阶乘 n! = n * (n-1) * (n-2) * ... * 1
// 那么我们可以将n个数相乘的大问题拆解成每个数和他的下一项相乘的小问题
//而结束的条件是什么呢?自然是当n = 0 或者 1 了,注意0的阶乘是1
function factorialRecursive(n){
//边界处理,负数没有阶乘
if(typeof n != 'number' || n < 0){
return '输入错误'
}
//递归终止条件
if(n === 1 || n === 0){
return 1
}
//自己调用自己
const occ = factorialRecursive(n-1)
result = n * occ //大问题 -小问题化
return result
}
好了,如果了解了这个,我们再来看看下面这道题。

我们要求出最大深度,但每一个节点都有可能分叉处为左右字树,如果一条一条路径去遍历,实在繁琐,因此我们可以采用递归。本质上是将求二叉树深度的问题拆解成求每一个节点左右子树深度的问题
我们可以利用二叉树天然的分治特性,每一个节点的最大深度即为它左右子树中的最大深度+1.
因此,要求二叉树的最大深度,只需要看其左右子树最大深度是谁,左右子树的最大深度又要看其左右子树的最大深度,依次向下,直到节点为null。最终依次向上返回结果。
来看一下代码如何书写
function maxDepth(root){
//终止条件
if(!root){
return 0
}
//左子树的最大深度等于其左右子树中的最大深度
let leftDepth = maxDepth(root.left)
//右子树的最大深度等于其左右子树中的最大深度
let rightDepth = maxDepth(root.right)
//节点的最大深度等于其左右子树中的最大深度+1
return Math.max(leftDpth,rightDepth)+1
}
其实当你想通如何拆解成同类型的小问题,就很好解决了。
6239

被折叠的 条评论
为什么被折叠?



