返回
LeetCode 经典二叉树算法剖析,通俗易懂,小白也能读懂!
后端
2023-11-03 23:12:48
征服二叉树:掌握 LeetCode 经典算法
作为程序员,理解二叉树的基本操作和算法至关重要。LeetCode,程序员面试的必备神器,自然少不了对二叉树算法的考察。让我们踏上一段旅程,深入剖析 LeetCode 中的经典二叉树算法,让小白程序员也能轻松掌握二叉树的精髓。
判断平衡二叉树
什么是平衡二叉树?
想象一棵二叉树像一棵树,左右两侧的树枝高度相差不大。这就是平衡二叉树。它的高度差在左右子树之间最多为 1。
算法步骤:
我们通过以下步骤来判断一棵二叉树是否平衡:
- 检查空树: 如果二叉树为空,它是平衡的。
- 获取左右子树高度: 计算二叉树的左子树和右子树的高度。
- 计算高度差: 计算左右子树高度差的绝对值。
- 递归检查: 如果高度差小于等于 1,并且左右子树也都是平衡的,则二叉树是平衡的。
代码示例:
public boolean isBalanced(TreeNode root) {
// 判断空树
if (root == null) {
return true;
}
// 获取左右子树高度
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
// 计算高度差
int heightDiff = Math.abs(leftHeight - rightHeight);
// 递归检查
return heightDiff <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int getHeight(TreeNode root) {
// 判断空树
if (root == null) {
return 0;
}
// 计算最大深度
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
二叉树的层序遍历
什么是层序遍历?
想像你从上方俯瞰一棵二叉树,你会看到它一层一层地排列。层序遍历就是按照这些层级顺序访问二叉树中的节点。
算法步骤:
- 使用队列: 创建一个队列来存储当前层级的节点。
- 遍历层级: 当队列不为空时,访问队列中的所有节点,并将它们的子节点放入队列中。
- 移动到下一层: 访问完当前层级的所有节点后,进入队列中的下一层级。
代码示例:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
// 加入根节点
if (root != null) {
queue.offer(root);
}
// 遍历层级
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
// 访问当前层级节点
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
// 加入子节点
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
// 加入结果
result.add(level);
}
return result;
}
二叉树的最近公共祖先
什么是最近公共祖先?
在二叉树中,两个节点的最近公共祖先是它们最近的共有祖先节点。
算法步骤:
- 特殊情况: 如果其中一个节点是另一个节点的祖先,则该节点是最近公共祖先。
- 递归: 否则,分别在左子树和右子树中查找节点,如果左右子树都找到了节点,则该节点是最近公共祖先。
- 继续递归: 如果只在一个子树中找到节点,则继续在该子树中递归查找。
代码示例:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 特殊情况
if (root == null || root == p || root == q) {
return root;
}
// 递归查找
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 判断结果
if (left != null && right != null) {
return root;
} else if (left != null) {
return left;
} else {
return right;
}
}
根据二叉树创建字符串
将二叉树转换成字符串
有时候我们需要将二叉树转换成字符串,比如进行序列化或输出。
算法步骤:
- 递归: 使用先序遍历来递归遍历二叉树。
- 拼接: 在遍历每个节点时,将其值添加到字符串中。
- 处理子树: 如果节点有子树,则将其放在括号内,并继续递归。
代码示例:
public String tree2str(TreeNode root) {
// 判断空树
if (root == null) {
return "";
}
// 拼接根节点
StringBuilder sb = new StringBuilder();
sb.append(root.val);
// 处理左子树
if (root.left != null) {
sb.append("(").append(tree2str(root.left)).append(")");
}
// 处理右子树
if (root.right != null) {
if (root.left == null) {
sb.append("()");
}
sb.append("(").append(tree2str(root.right)).append(")");
}
return sb.toString();
}
结语
通过剖析这些经典算法,我们深入了解了二叉树的基本操作和算法思想。这些算法是解决二叉树问题的基石,掌握它们对于提升编程能力和面试表现至关重要。希望本文能够帮助小白程序员快速入门二叉树,成为算法界的明日之星!
常见问题解答
- 什么是二叉树的高度? 二叉树的高度是从根节点到最远叶节点的最长路径长度。
- 二叉搜索树和普通二叉树有什么区别? 二叉搜索树是一个特殊的二叉树,其中每个节点的值都比其左子树的所有值大,比其右子树的所有值小。
- 如何在二叉树中查找节点? 可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法来查找二叉树中的节点。
- 如何插入节点到二叉搜索树中? 在二叉搜索树中插入节点需要遵循二叉搜索树的性质,将新节点插入到正确的位置。
- 二叉树遍历有哪些常见的类型? 除了层序遍历之外,还有先序遍历、中序遍历和后序遍历等常见的二叉树遍历类型。