image

对递归类算法的小总结


writerlIcht                      emaillIcht.gzl@gmail.com                 date:  2019.10.1

 

 

10

        最近刷leetcode时遇到的树类题目的解答多半是对迭代方法的训练,想不到窍门可能那一小时就白白没了。递归、迭代类题目做得好不好的区别可能就是几十行代码和两三行代码的区别了,惊叹评论区大佬简单几行代码的神级操作,有时连光看都要理解半天,也多亏这些大佬的解答,也给我带来了很多技巧上的帮助,对递归类的题目也不会像以前那样无从下手了,这类题目同样存在某些套路。

 

 

递归三部曲

        面对一道递归类的题目,我们总会忍不住想着从最开始怎么一层一层迭代,把每层的迭代细节都想明白,以至于越想越多越想越复杂,陷入困境。其实在着手递归问题应该从大局入手,首先要思考的是在一次迭代中的问题,也只需要重点考虑仅仅一次递归的流程就好了,比如这次递归中的出口、操作、返回值等。总的来说可以分为三步:

    1、找整个递归的终止条件:递归应该在什么时候结束?

    2、找返回值:应该给上一级返回什么信息?

    3、本级递归应该做什么:在这一级递归中,应该完成什么任务?

    接下来是leetcode里面的例子:

 

 

例子

 

一、寻找二叉树的最大深度:

104. 二叉树的最大深度

image

解题过程:

 

1、递归的终止条件:当然是树为空的时候,此时树的深度为0,递归就结束了。

2、递归的返回值:最大深度,也就是一次递归中两子树之中的最大深度,整形数值。

3、先思考在此次递归中,一次递归要处理哪些东西,无疑是一个节点以及其两个子节点,需要得到他们的高度信息,返回两个子节点的深度的最大值。那么本级递归应该做什么就很明确了,自然就是在root的左右子树中选择较大的一个,再加上1就是以root为根的子树的最大深度了,然后再返回这个深度即可。

    Python实现方式如下:

 Java实现方式:

 

二、两两交换链表中的节点:

Leetcode 24. 两两交换链表中的节点

image

解题过程:

1、递归终止条件:剩下一个或者当前为最后节点时,就没办法进行一次交换了,此时返回。此时返回链表头。

2、递归的返回值:返回已处理结束的链表头,也就是已经交换结束后的链表头。

3、一次递归的处理:要交换链表的前两个节点,然后将已处理的链表(function(list_rest))拼接到这两个节点后。node 记录的head.next的位置会跟着 head.next 与 head的交换一起动,之中指向head.next这一地址,所以返回上一级的链表的头始终是head.next也就是nede.next(在一次过程中会head与head.next的位置,所以node会被换到最前面)

 Python实现方式:

 Java实现方式:

 

三、判断平衡二叉树:

Leetcode 110. 平衡二叉树

image

解题过程:

1、递归的终止条件:子树为空的时候,空树自然是平衡二叉树了。

2、递归的返回信息:由题意不难知道应该返回bool类型,但是在递归中要传递返回处理的应该是节点的信息才对,最后才对平衡与否进行判断返回bool类型,因此,我们可以新定义一个函数来记录节点深度信息并判断节点是否是平衡二叉树。

3、目前树有三个节点:root,left,right。我们首先判断left子树和right子树是否是平衡二叉树,如果不是则直接返回false。再判断两树高度差是否不大于1,如果大于1也直接返回false。否则说明以root为节点的子树是平衡二叉树,那么就返回true和它的高度。

 Python实现方式:

 Java实现方式:

 更多相关题型 :

Leetcode 101. 对称二叉树

Leetcode 111. 二叉树的最小深度

Leetcode 226. 翻转二叉树

Leetcode 617. 合并二叉树

Leetcode 654. 最大二叉树

Leetcode 83. 删除排序链表中的重复元素

Leetcode 206. 翻转链表

 

 参考原文出处:http://39.96.217.32/blog/4