144. 二叉树的前序遍历
- 前序遍历(中左右),迭代遍历栈模拟
- 入栈的顺序为中,右,左,,弹出顺序为中,左,右,入栈之前判断节点是否为空,空节点不入栈
145. 二叉树的后序遍历
- 后序遍历(左右中),迭代遍历栈模拟
- 入栈顺序为中,左,右,弹出顺序为中,右,左,再反转节点顺序为左,右,中
94. 二叉树的中序遍历
- 中序遍历(左中右),迭代遍历栈模拟
- 入栈顺序为左,中,右,一直访问根节点的左子树直到不为空,放入栈中,如果当前节点为空,当前节点弹出栈,当前节点的值放入结果集中,然后访问当前节点右子树
102. 二叉树的层序遍历
- 广度优先遍历,迭代遍历利用队列
- 层序遍历,判断根节点是否为空,如果不为空就加入队列,当队列不为空时,计算队列的长度,
for
循环中,取出队头元素,加入结果集,然后加入当前节点的左子树和当前节点的右子树
226.翻转二叉树
- 层序遍历的模板也能解决,在
for
循环中,取出队头元素后,开始交换左子树和右子树的节点就可以
101. 对称二叉树
- 递归遍历,参数:根节点的左子树和根节点的右子树,相当于根节点为对称轴
- 终止条件:左为空,右不为空,不对称,左不为空,右为空,不对称,左右都为空,对称,左右子树的值不相等,不对称
- 单层递归逻辑:先比较外侧节点,左子树的左边和右子树的右边,比较内侧节点,左子树的右边和右子树的左边,如果两个递归返回的值相等,就是对称
104.二叉树的最大深度
- 最大深度利用层序遍历解决,设置一个计数器,每次计算出队列的长度之后,
count++
111. 二叉树的最小深度
- 最小深度是根节点到最近的叶子节点的深度,层序遍历,当遍历到的节点左右孩子都为空说明遇到叶子节点。
- 同样在统计队列长度时,
depth++
,多加一个判断条件,左右孩子是否为空,如果为空,return depth
222. 完全二叉树的节点个数
- 层序遍历统计节点个数,在
for
循环中放入计数器,count++
110.平衡二叉树
- 平衡二叉树是左右子树的高度差的绝对值不超过1
- 递归参数:当前节点,起初也就是根节点
- 终止条件:如果节点为空,返回0
- 分别求出左右子树的高度,再计算差值,后序遍历(左右中),如果差值等于-1,就返回-1,如果绝对值差值不超过1,当前节点的高度为
1+max(左子树高度,右子树高度)
257. 二叉树的所有路径
- 需要把每条路径都记录下来,用递归,涉及到回溯
- 前序遍历,递归参数:当前节点,起初为根节点,收集单条路径的数组,收集所有路径的结果集
- 递归终止条件:如果当前节点为空,返回
- 单层递归逻辑:中:
path
先收集单条路径的节点,接下来判断当前节点的左右孩子是否为空,如果为空,说明遇到叶子节点,此时单条路径就到头了,result
收集单条路径的节点,因为是遇到叶子节点才返回,所以必须要在判读是否叶子节点之前就开始加入path
。 - 左:递归左子树,单条路径
pop
- 右:递归右子树,单条路径
pop
404.左叶子之和
- 左叶子:当前节点的左节点不为空,当前节点的左节点的左节点为空,当前节点的左节点的右节点为空,就找到了左叶子
- 以根节点为对称轴,分别找左子树的左叶子节点和右子树的左叶子节点,两个左子树和右子树的左叶子相加就得到结果
513.找树左下角的值
- 树的最后一行,最左边的值,利用层序遍历,遍历至最后一层,第一个元素就是最左边的值
112. 路径总和
- 判断树中的路径节点值相加等于目标和,在遍历的过程中,利用目标和相减,最终目标和为0就找到了这一路径,如果不为0,就没有找到
- 递归有返回值,前序遍历,中左右
106. 从中序与后序遍历序列构造二叉树
- 中序遍历(左中右),后序遍历(左右中),后序遍历数组中的最后一个是一定是根节点,找出它并创建树的新节点
- 根据上述找到的根节点,找出中序遍历中左右区间,也就是切割点,用
vector数组收集左右区间
- 得到左右区间之后,在后序遍历中,舍弃最后一个根节点元素,找出子树的根节点
- 根据中序数组得到的左右区间,开始切割后序数组,用
vector数组收集
- 层层递归切割数组,参数为中序,后序数组
654.最大二叉树
- 通过数组构建最大二叉树,根节点最大,左子树通过数组中最大值左边部分构造,右子树通过数组中最大值右边部分构造
- 前序遍历,递归构造(中左右)
- 先找出数组中的最大值,
for
循环遍历找出最大值和最大值下标 - 最大值创建为根节点
- 如果最大值大于0,保证左区间有数值,递归创建左子树,参数为左区间
- 最大值小于数组大小,递归创建右子树,参数为右区间
617.合并二叉树
- 遍历两颗树的节点相加和遍历一棵树传入两个树的节点是一样的
- 前序遍历递归,中处理逻辑:创建新节点,新节点的值为两棵树的节点相加
700.二叉搜索树中的搜索
- 二叉搜索树,按照左小右大判断左子树还是右子树
- 递归遍历,如果根节点的值等于整数值,返回根节点,如果根节点大于该值,寻找根节点的左子树,如果根节点小于该值,寻找根节点的右子树
98. 验证二叉搜索树
- 验证二叉搜索树,相当于判断序列是不是递增的,中序遍历是有序递增的序列
- 先中序遍历得到有序数组,然后遍历该数组,如果前一个元素大于后一个元素说明不是有序的序列
530.二叉搜索树的最小绝对差
- 将二叉搜索树变为有序的数组,中序遍历得到有序数组
- 遍历数组,利用数组中元素两两相减得到最小差值
501. 二叉搜索树中的众数
- 递归遍历树得到序列数组,
unorder_map集合
收集元素,key表示元素,value表示频率
- 按照频率排序,先将map放入数组中,然后定义排序规则,按照频率排序
- 取数组中第一个元素为最高频元素,放入结果集中,继续在数组中遍历寻找同样频率的元素,也放入结果集中
236. 二叉树的最近公共祖先
- 寻找最近的公共祖先,选择后序遍历,左右中
- 终止条件:如果当前节点等于p,q两个节点,返回当前节点的根节点
- 左右处理逻辑:递归遍历返回节点
- 中处理逻辑,如果左右递归返回的节点都不为空,返回根节点;如果左右递归返回的节点有一个为空,返回的节点是另一个不为空的,都为空,返回空
235. 二叉搜索树的最近公共祖先
- 遍历顺序任意,选择前序遍历,中左右
- 中:判断当前节点的值与
q,p
值得大小,选择遍历左子树还是右子树,递归返回得节点,然后return
450.删除二叉搜索树中的节点
- 中处理逻辑, 分为五种情况,1.没找删除节点;2.左右孩子为空,直接删;3.左为空,右不为空,删除节点,右孩子补位;4.右为空,左不为空,删除节点,左孩子补位;5.左右都不为空,删除节点得左孩子就放到右孩子得最左边,右孩子补位
- 左右逻辑,根据节点值大小搜索
669. 修剪二叉搜索树
- 中处理逻辑,需要判断节点值与区间的值大小,才决定遍历左子树还是右子树,递归返回节点
108. 将有序数组转换为二叉搜索树
- 一个有序数组,切割数组,中序遍历,数组的中间值为根节点,从根节点处分为左区间和右区间,左右递归分别传入的根节点左区间和右区间
538.把二叉搜索树转换为累加树
- 从树的最大值处开始累加,树的最右边为最大值, 遍历顺序为:右中左,反中序遍历
- 中处理逻辑:设置一个
pre
节点,用来统计当前节点的累加值,并记录当前节点的值,先累加,再记录累加值之后的值