description:前序+中序 / 中序+后序返回树想破脑袋,然后以后要每天花 monring 来复习考试内容,一日之际在于晨,每天题量直接 cut off。接下来是篇关于树的文章,可以好好了解一下。树里我踩过的坑。
Monday
102.二叉树的层序遍历
递归思路:仍然是先深度到顶确定好 deep 把每一深度的 ArrayList new 出来,再往里依次添值。
是否创建 ArrayList 用 if 判断,进了递归的方法 deep 就要 +1,因为递归进递归会先走到 left 的底,再依次出递归 deep 只会回到原来的值。总之每次进递归的方法的初始参数都是当前参数中的结点、参数节点的上一深度,然后 deep++,就变成了当前节点、当前节点深度操作。
这题二刷肯定思路从0开始,大家都这样,不要放弃!!!
迭代思路(推荐):利用队列的先进先出,起初队列只有一个 root ,然后构建一个循环(在每次循环都新建一个 ArrayList ,代表存每一个深度的所有元素值,该循环内嵌套一个循环拜访每个该深度的结点的值进 ArrayList 以及该节点的左右孩子并 offer 进队列。问题来了:如何判断每个深度有几个树节点?即如何确定内存循环的循环次数 ?在每次进外层循环时,都把当前的队列长度都定义到 len 变量上,该队列每次把一层的树节点长度记录下来,全都 poll 掉了剩下的就是下一深度的所有树节点。外循环应该好判断的吧 ? 当队列为空时,即整个深度 offer 不进去树节点时,就意味着全部遍历完了。
107.二叉树的层次遍历II
就是用上题的迭代再反转,反转就把装有ArrayList的 list 从尾到头的 add 到另一个 result 就行。
199.二叉树的右视图
利用层序迭代遍历留住每层的最后一个元素值。
637.二叉树的层平均值
还是层序遍历。
Tuesday
429.N叉树的层序遍历
主要注意定义的 Node ,有属性名为 children 的 List ,里面全是当前节点的孩子,再正常层序遍历就好了。
515.在每个树行中找最大值
类似层序遍历留住最后一个元素。
116.填充每个节点的下一个右侧节点指针
思路:很简单,自己用层序遍历套娃。
注意:老是忘记 offer root 结点进入队列,进入了就容易在 len 上判断失误:
需要判断 len 是否等于 1 ,如果队列为空了,peek 出来就是 null 。但是队列在下一层有元素时,并不会为 null ,所以需要 len 来判断当前值。
117.填充每个节点的下一个右侧节点指针II
和116的差距就是这里不是完全二叉树,逻辑代码都一样。
104.二叉树的最大深度
做了前面的还不会请自行gg…
111.二叉树的最小深度
有坑,不是说 root.left 节点为空最小深度就是1,是从根节点到最近叶子节点。只有一个结点的 left、right 都为 null ,才是叶子节点。
注意:一定要在第一步判空: if(root == null) …
Wednesday
226.翻转二叉树
递归:确定参数类型、返回值 —> 确定终止条件 —> 确定单层逻辑。先 coding 出交换代码的单层逻辑,再左右子树递归。
层序遍历在内层循环也能处理。
101. 对称二叉树
不管是递归还是迭代,都要判断比较的两个节点都为 null、一个为 null、两个都不为 null是否相等。
递归很好做,但是不能很好地理解题意。单层逻辑就是判断以上条件并 return 两两结点再进该方法。
迭代:利用队列,推入二层的两个节点,所有判空都在循环中进行。然后推四个孩子。
其实还是迭代更具普适性。
100.相同的树
递归:同101,不过在递归的参数 node1 和 node2 都为 null 容易不理解(101就迷糊了的问题),为什么返回 null,返回 null 并不会结束整个程序,只会把那一层递归的程序结束,最后 return 的是两个判断的 &&。
迭代:同101。
572.另一个树的子树
据题意,该 t 树要么是等于 s 树,要么是其左子树 or 右子树。定义一个判断是否相等树的方法,再 || 到两个 isSubtree 方法。
注意:在 isSubtree 方法一定要判空 s 结点,不然就算在 isSametree 方法中能判空,再进到 isSubtree 也还是空,再 isSubtree.left 就空指针了。就算刚开始传入的 s 不为 null,但是 s 一直在变化,总会有出现 null 的情况出现。任何一个递归一定是有一个结束条件来收敛!
222.完全二叉树的节点个数
迭代:一个循环粗糙层序遍历。
递归:return 1+左递归+右递归。
注意:用 offer 要判空“值”,poll 不需要判空“队列”。
Thursday
110.平衡二叉树
思路:没什么东西,bfs、dfs都行,两个相减再用两个孩子递归。
注意:在处理deep时要抠清楚,正常相减 deep 起始值无所谓,但是,如果节点为 null 那返回的一定是 0,deep 初始值只与这里有关。
拓展:bfs 万精油, dfs 前序求深度,后序求高度。
257. 二叉树的所有路径
思路:跟深度相关,首选 dfs的前序遍历,然后肯定是要递归的,在此之上还要回溯:进到多少层,结束了再出来,出一层删最后一个元素,出n层删n个元素。两个list都放做递归方法的参数,因为两个都要保持不变得用,所有操作都要手动做!递归的结束条件是当前节点的左右孩子为空。
404.左叶子之和
思路:不同条件进不同的处理,当前结点(左节点)为不为叶子结点要判断,当前节点的右节点为不为空也要判断。
注意:一定要判断是否为叶子结点,是求左叶子结点和,不是左节点和。
513.找树左下角的值
思路:层序遍历只保存最左边的值,很简单,有足够的时间优雅一点!
112. 路径总和
思路:主要就是递归+回溯,和257差不多。
注意:return 是结束当前递归层,如果要影响到其他层,则需要具有传递性的语句。
Friday
113. 路径总和 ll
思路:和 day 19 的 112 差不多思路(递归+回溯),不同之处在于判空处理。因为是要存入路径,所以参数多了两个 List:一个用于存多条路径,一个用于增删单条路径。
注意:这条增删单条路径的,在判空捕捉到 add 该条路径时,必须 new 一个新的 List ,不然还是操作的那条是始终在变的。
持续更新…
如有错误,敬请斧正!!!