本周小结!(二叉树系列三)

假期让人感觉时光飞逝!
本周小结是不是感觉这周过的非常快 , 好像刚刚做完本周小结 , 又要做本周小结了 , 果然假期让人感觉时光飞逝 , 哈哈 。
周一在二叉树:以为使用了递归 , 其实还隐藏着回溯 中 , 通过leetcode 257.二叉树的所有路径这道题目 , 讲解了递归如何隐藏着回溯 , 一些代码会把回溯的过程都隐藏了起来了 , 甚至刷过这道题的同学可能都不知道自己用了回溯 。
文章中第一版代码把每一个细节都展示了输出来了 , 大家可以清晰的看到回溯的过程 。
然后给出了第二版优化后的代码 , 分析了其回溯隐藏在了哪里 , 如果要把这个回溯扣出来的话 , 在第二版的基础上应该怎么改 。
主要需要理解:「回溯隐藏在traversal(cur->left, path + "->", result);中的 path + "->" 。 每次函数调用完 , path依然是没有加上"->" 的 , 这就是回溯了 。 」
周二在文章二叉树:做了这么多题目了 , 我的左叶子之和是多少? 中提供了另一个判断节点属性的思路 , 平时我们习惯了使用通过节点的左右孩子判断本节点的属性 , 但发现使用这个思路无法判断左叶子 。
此时需要相连的三层之间构成的约束条件 , 也就是要通过节点的父节点以及孩子节点来判断本节点的属性 。
这道题目可以扩展大家对二叉树的解题思路 。
周三在二叉树:我的左下角的值是多少? 中的题目如果使用递归的写法还是有点难度的 , 层次遍历反而很简单 。
题目其实就是要在树的「最后一行」找到「最左边的值」 。
「如何判断是最后一行呢 , 其实就是深度最大的叶子节点一定是最后一行 。 」
在这篇文章中 , 我们使用递归算法实实在在的求了一次深度 , 然后使用靠左的遍历 , 保证求得靠左的最大深度 , 而且又一次使用了回溯 。
如果对二叉树的高度与深度又有点模糊了 , 在看这里二叉树:我平衡么? , 回忆一下吧 。
二叉树:我的左下角的值是多少? 中把我们之前讲过的内容都过了一遍 , 此外 , 还用前序遍历的技巧求得了靠左的最大深度 。
「求二叉树的各种最值 , 就想应该采用什么样的遍历顺序 , 确定了遍历循序 , 其实就和数组求最值一样容易了 。 」
周四在二叉树:递归函数究竟什么时候需要返回值 , 什么时候不要返回值? 中通过两道题目 , 彻底说清楚递归函数的返回值问题 。
一般情况下:「如果需要搜索整颗二叉树 , 那么递归函数就不要返回值 , 如果要搜索其中一条符合条件的路径 , 递归函数就需要返回值 , 因为遇到符合条件的路径了就要及时返回 。 」
特别是有些时候 递归函数的返回值是bool类型 , 一些同学会疑惑为啥要加这个 , 其实就是为了找到一条边立刻返回 。
其实还有一种就是后序遍历需要根据左右递归的返回值推出中间节点的状态 , 这种需要有返回值 , 例如222.完全二叉树 , 110.平衡二叉树 , 这几道我们之前也讲过 。
周五之前都是讲解遍历二叉树 , 这次该构造二叉树了 , 在二叉树:构造二叉树登场 中 , 我们通过前序和中序 , 后序和中序 , 构造了唯一的一颗二叉树 。
「构造二叉树有三个注意的点:」

  • 分割时候 , 坚持区间不变量原则 , 左闭右开 , 或者左闭又闭 。
  • 分割的时候 , 注意后序 或者 前序已经有一个节点作为中间节点了 , 不能继续使用了 。
  • 如何使用切割后的后序数组来切合中序数组?利用中序数组大小一定是和后序数组的大小相同这一特点来进行切割 。
这道题目代码实现并不简单 , 大家啃下来之后 , 二叉树的构造应该不是问题了 。
「最后我还给出了为什么前序和后序不能唯一构成一棵二叉树 , 因为没有中序遍历就无法确定左右部分 , 也就无法分割 。 」
周六知道了如何构造二叉树 , 那么使用一个套路就可以解决文章二叉树:构造一棵最大的二叉树 中的问题 。


推荐阅读