1. 二叉树基础与LeetCode高频题解析
二叉树是数据结构中最基础也最重要的非线性结构之一,在算法面试中出现的频率极高。标题中提到的144、145、94等数字对应的是LeetCode平台上关于二叉树的经典题目编号,这些题目涵盖了二叉树的各种遍历方式和基础操作。
1.1 二叉树的基本概念
二叉树(Binary Tree)是每个节点最多有两个子节点的树结构,通常称为左子节点和右子节点。它具有以下重要特性:
- 第i层最多有2^(i-1)个节点
- 深度为k的二叉树最多有2^k-1个节点
- 对于任何非空二叉树,如果叶子节点数为n0,度为2的节点数为n2,则n0 = n2 + 1
二叉树常见的存储方式有两种:
- 链式存储:通过节点对象和指针连接
- 顺序存储:使用数组表示,对于索引为i的节点,其左子节点为2i+1,右子节点为2i+2
python复制class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
1.2 LeetCode二叉树题目分类
标题中提到的题目编号可以分为以下几类:
-
遍历类题目:
-
- 二叉树的前序遍历
-
- 二叉树的中序遍历
-
- 二叉树的后序遍历
-
- 二叉树的层序遍历
-
-
基本操作类题目:
-
- 翻转二叉树
-
- 对称二叉树
-
- 二叉树的最大深度
-
- 二叉树的最小深度
-
- 完全二叉树的节点个数
-
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 二叉树遍历的四种经典方式
二叉树的遍历是解决几乎所有二叉树问题的基础,必须熟练掌握递归和迭代两种实现方式。
2.1 前序遍历(144题)
前序遍历的顺序是:根节点 → 左子树 → 右子树。这是最自然的遍历方式,适合用来复制树的结构。
递归实现:
python复制def preorderTraversal(root):
res = []
def helper(node):
if not node:
return
res.append(node.val)
helper(node.left)
helper(node.right)
helper(root)
return res
迭代实现(使用栈):
python复制def preorderTraversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
2.2 中序遍历(94题)
中序遍历的顺序是:左子树 → 根节点 → 右子树。对二叉搜索树使用中序遍历可以得到有序序列。
递归实现:
python复制def inorderTraversal(root):
res = []
def helper(node):
if not node:
return
helper(node.left)
res.append(node.val)
helper(node.right)
helper(root)
return res
迭代实现:
python复制def inorderTraversal(root):
res, stack = [], []
curr = root
while curr or stack:
while curr:
stack.append(curr)
curr = curr.left
curr = stack.pop()
res.append(curr.val)
curr = curr.right
return res
2.3 后序遍历(145题)
后序遍历的顺序是:左子树 → 右子树 → 根节点。常用于释放树的内存或计算表达式树的值。
递归实现:
python复制def postorderTraversal(root):
res = []
def helper(node):
if not node:
return
helper(node.left)
helper(node.right)
res.append(node.val)
helper(root)
return res
迭代实现(前序遍历的变种):
python复制def postorderTraversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
2.4 层序遍历(102题)
层序遍历按照树的层级从上到下、从左到右访问节点,需要使用队列辅助实现。
迭代实现:
python复制def levelOrder(root):
if not root:
return []
queue, res = collections.deque([root]), []
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res
提示:层序遍历的变种非常多,包括锯齿形遍历、右视图、每层最大值等,都是基于这个模板的变形。
3. 二叉树基本操作题目解析
3.1 翻转二叉树(226题)
翻转二叉树是二叉树操作中最经典的题目之一,实际上就是交换每个节点的左右子树。
递归解法:
python复制def invertTree(root):
if not root:
return None
root.left, root.right = root.right, root.left
invertTree(root.left)
invertTree(root.right)
return root
迭代解法(使用前序遍历框架):
python复制def invertTree(root):
if not root:
return None
stack = [root]
while stack:
node = stack.pop()
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return root
3.2 对称二叉树(101题)
判断二叉树是否对称,实际上是判断左右子树是否镜像对称。
递归解法:
python复制def isSymmetric(root):
if not root:
return True
def helper(left, right):
if not left and not right:
return True
if not left or not right:
return False
return left.val == right.val and helper(left.left, right.right) and helper(left.right, right.left)
return helper(root.left, root.right)
迭代解法(使用队列):
python复制def isSymmetric(root):
if not root:
return True
queue = collections.deque([(root.left, root.right)])
while queue:
left, right = queue.popleft()
if not left and not right:
continue
if not left or not right:
return False
if left.val != right.val:
return False
queue.append((left.left, right.right))
queue.append((left.right, right.left))
return True
3.3 二叉树的最大深度(104题)
计算二叉树的最大深度是基础但重要的问题,可以很好地理解递归在树结构中的应用。
递归解法:
python复制def maxDepth(root):
if not root:
return 0
return max(maxDepth(root.left), maxDepth(root.right)) + 1
迭代解法(使用层序遍历):
python复制def maxDepth(root):
if not root:
return 0
queue, depth = collections.deque([root]), 0
while queue:
depth += 1
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return depth
3.4 二叉树的最小深度(111题)
最小深度与最大深度不同,需要注意只有当一个节点左右子节点都为空时才是叶子节点。
递归解法:
python复制def minDepth(root):
if not root:
return 0
if not root.left and not root.right:
return 1
if not root.left:
return minDepth(root.right) + 1
if not root.right:
return minDepth(root.left) + 1
return min(minDepth(root.left), minDepth(root.right)) + 1
迭代解法(使用层序遍历):
python复制def minDepth(root):
if not root:
return 0
queue, depth = collections.deque([(root, 1)]), 0
while queue:
node, depth = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append((node.left, depth + 1))
if node.right:
queue.append((node.right, depth + 1))
return depth
3.5 完全二叉树的节点个数(222题)
对于普通二叉树,计算节点个数可以直接遍历所有节点。但对于完全二叉树,可以利用其特性进行优化。
普通解法(适用于任何二叉树):
python复制def countNodes(root):
if not root:
return 0
return 1 + countNodes(root.left) + countNodes(root.right)
优化解法(利用完全二叉树性质):
python复制def countNodes(root):
if not root:
return 0
left_height = right_height = 0
left, right = root, root
while left:
left_height += 1
left = left.left
while right:
right_height += 1
right = right.right
if left_height == right_height:
return (1 << left_height) - 1
return 1 + countNodes(root.left) + countNodes(root.right)
4. 二叉树问题的解题技巧与常见错误
4.1 递归与迭代的选择
递归解法通常更简洁,但需要注意:
- 递归深度过大可能导致栈溢出
- 重复计算问题(可以使用记忆化优化)
- 尾递归优化(某些语言支持)
迭代解法通常更高效,但:
- 需要手动维护栈或队列
- 代码可能更复杂
- 某些问题难以用迭代表达
提示:面试中通常需要掌握两种实现方式,实际开发中根据具体情况选择。
4.2 边界条件处理
二叉树问题中常见的边界条件包括:
- 空树(root为None)
- 只有根节点的树
- 只有左子树或只有右子树的树
- 完全倾斜的树(类似链表结构)
4.3 常见错误与调试技巧
- 忘记处理空节点导致NullPointerException
- 递归终止条件不正确导致无限递归
- 混淆前序、中序、后序的访问顺序
- 层序遍历中忘记记录当前层的节点数
- 修改树结构时丢失引用(如翻转子树时)
调试技巧:
- 使用小规模的树进行测试(空树、单节点、三个节点等)
- 打印中间结果(如在递归中打印当前节点值)
- 可视化工具辅助理解(如绘制二叉树结构)
4.4 时间复杂度分析
不同操作的时间复杂度:
- 遍历操作:O(n),n为节点数
- 查找操作:普通二叉树O(n),二叉搜索树平均O(logn)
- 空间复杂度:递归O(h),h为树高;迭代取决于使用的数据结构
对于完全二叉树,h=log(n),因此很多操作可以优化到O(logn)的时间复杂度。
