二叉树
知识点
二叉树遍历
前序遍历:先访问根节点,再前序遍历左子树,再前序遍历右子树 中序遍历:先中序遍历左子树,再访问根节点,再中序遍历右子树 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问根节点
注意点
以根访问顺序决定是什么遍历
左子树都是优先右子树
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init(_ val: Int) {
self.val = val
self.left = nil
self.right = nil
}
}前序递归
前序非递归
中序非递归
后序非递归
注意点
核心就是:根节点必须在右节点弹出之后,再弹出
DFS 深度搜索-从上到下
DFS 深度搜索-从下向上(分治法)
注意点:
DFS 深度搜索(从上到下) 和分治法区别:前者一般将最终结果通过指针参数传入,后者一般递归返回结果最后合并
BFS 层次遍历
分治法应用
先分别处理局部,再合并结果
适用场景
快速排序
归并排序
二叉树相关问题
分治法模板
递归返回条件
分段处理
合并结果
典型示例
归并排序
注意点
递归需要返回结果用于合并
快速排序
注意点:
快排方法一由于是原地交换所以没有合并过程 传入的索引是存在的索引(如:0、count-1 等),越界可能导致崩溃
常见题目示例
maximum-depth-of-binary-tree
给定一个二叉树,找出其最大深度。
思路:分治法
balanced-binary-tree
给定一个二叉树,判断它是否是高度平衡的二叉树。
思路:分治法,左边平衡 && 右边平衡 && 左右两边高度 <= 1,
binary-tree-maximum-path-sum
给定一个非空二叉树,返回其最大路径和。
思路:分治法,dfs递归求某节点的最大贡献值,同时计算最大路径
lowest-common-ancestor-of-a-binary-tree
lowest-common-ancestor-of-a-binary-tree
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
思路:分治法,有左子树的公共祖先或者有右子树的公共祖先,就返回子树的祖先,否则返回根节点
BFS 层次应用
binary-tree-level-order-traversal
binary-tree-level-order-traversal
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)
思路:用一个队列记录一层的元素,然后扫描这一层元素添加下一层元素到队列(一个数进去出来一次,所以复杂度 O(logN))
binary-tree-level-order-traversal-ii
binary-tree-level-order-traversal-ii
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
思路:在层级遍历的基础上,翻转一下结果即可
binary-tree-zigzag-level-order-traversal
binary-tree-zigzag-level-order-traversal
给定一个二叉树,返回其节点值的锯齿形层次遍历。Z 字形遍历
二叉搜索树应用
validate-binary-search-tree
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
思路 1:中序遍历,检查结果列表是否已经有序
思路 2:分治法,判断左 MAX < 根 < 右 MIN
insert-into-a-binary-search-tree
insert-into-a-binary-search-tree
给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。
思路:找到最后一个叶子节点满足插入条件即可
总结
掌握二叉树递归与非递归遍历
理解 DFS 前序遍历与分治法
理解 BFS 层次遍历
练习
最后更新于
这有帮助吗?