1. 二叉树刷题指南:LeetCode 110-98题精解
作为一名经历过上百场技术面试的工程师,我深知二叉树在算法面试中的核心地位。今天我想分享LeetCode编号110到98的十道二叉树题目实战解析,这些题目覆盖了平衡判断、路径搜索、构造合并等经典题型,都是大厂面试的高频考点。
记得我最初刷题时,面对二叉树的多种遍历方式和递归非递归实现经常混淆。经过系统整理后,我发现只要掌握几个关键解题模板,配合适当的剪枝优化,大部分二叉树问题都能迎刃而解。下面我就用这十道题目为例,演示如何拆解二叉树问题的思考过程。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目分类与核心解法
2.1 平衡二叉树判定(LeetCode 110)
判断二叉树是否高度平衡是基础中的基础。关键在于理解平衡二叉树的定义:每个节点的左右子树高度差不超过1。我推荐使用后序遍历的递归解法:
python复制def isBalanced(root):
def height(node):
if not node:
return 0
left = height(node.left)
right = height(node.right)
if left == -1 or right == -1 or abs(left - right) > 1:
return -1
return max(left, right) + 1
return height(root) != -1
注意:在计算高度的同时进行平衡性判断,时间复杂度优化到O(n)。常规的先计算高度再比较的方法会导致O(n^2)时间复杂度。
2.2 二叉树路径问题(LeetCode 257, 112)
257题要求找出所有根到叶子的路径,112题则是判断是否存在路径和等于目标值。这两题可以共用相似的DFS框架:
python复制# 257题解法
def binaryTreePaths(root):
def dfs(node, path):
if not node:
return
path += str(node.val)
if not node.left and not node.right:
res.append(path)
return
path += "->"
dfs(node.left, path)
dfs(node.right, path)
res = []
dfs(root, "")
return res
对于112题,只需修改终止条件和递归逻辑:
python复制def hasPathSum(root, target):
if not root:
return False
if not root.left and not root.right:
return root.val == target
return hasPathSum(root.left, target - root.val) or hasPathSum(root.right, target - root.val)
2.3 特殊节点统计(LeetCode 404, 513)
404题求左叶子节点之和,513题找最底层最左边的值。这两题考察的是对节点特殊属性的判断:
python复制# 404题解法
def sumOfLeftLeaves(root):
if not root:
return 0
if root.left and not root.left.left and not root.left.right:
return root.left.val + sumOfLeftLeaves(root.right)
return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right)
# 513题解法(BFS)
def findBottomLeftValue(root):
queue = [root]
while queue:
node = queue.pop(0)
if node.right:
queue.append(node.right)
if node.left:
queue.append(node.left)
return node.val
技巧:513题使用BFS时先右后左的入队顺序,可以确保最后访问的节点就是最底层最左边的节点。
3. 二叉树构造与合并
3.1 中序+后序构建二叉树(LeetCode 106)
这是经典的二叉树重构问题。关键点在于确定根节点位置和左右子树的区间划分:
python复制def buildTree(inorder, postorder):
if not inorder:
return None
root_val = postorder[-1]
root = TreeNode(root_val)
idx = inorder.index(root_val)
root.left = buildTree(inorder[:idx], postorder[:idx])
root.right = buildTree(inorder[idx+1:], postorder[idx:-1])
return root
时间复杂度分析:
- 每次查找根节点位置需要O(n)时间
- 最坏情况下(树退化为链表)时间复杂度O(n^2)
- 可以通过哈希表预处理中序序列优化到O(n)
3.2 最大二叉树构造(LeetCode 654)
这道题要求根据数组构造最大二叉树,体现了分治思想的应用:
python复制def constructMaximumBinaryTree(nums):
if not nums:
return None
max_val = max(nums)
max_idx = nums.index(max_val)
root = TreeNode(max_val)
root.left = constructMaximumBinaryTree(nums[:max_idx])
root.right = constructMaximumBinaryTree(nums[max_idx+1:])
return root
优化方向:
- 使用线段树快速查询区间最大值
- 使用单调栈实现O(n)解法
3.3 二叉树合并(LeetCode 617)
合并两棵二叉树的简单递归解法:
python复制def mergeTrees(t1, t2):
if not t1:
return t2
if not t2:
return t1
t1.val += t2.val
t1.left = mergeTrees(t1.left, t2.left)
t1.right = mergeTrees(t1.right, t2.right)
return t1
迭代解法可以使用队列同时层序遍历两棵树。
4. 二叉搜索树专题
4.1 二叉搜索树搜索(LeetCode 700)
BST搜索的标准模板:
python复制def searchBST(root, val):
while root:
if root.val == val:
return root
root = root.left if val < root.val else root.right
return None
4.2 验证二叉搜索树(LeetCode 98)
这道题常见的陷阱是仅比较节点与左右子节点的值。正确做法需要维护上下界:
python复制def isValidBST(root):
def helper(node, lower=float('-inf'), upper=float('inf')):
if not node:
return True
if node.val <= lower or node.val >= upper:
return False
return helper(node.left, lower, node.val) and helper(node.right, node.val, upper)
return helper(root)
中序遍历解法:
python复制def isValidBST(root):
stack, prev = [], float('-inf')
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
if root.val <= prev:
return False
prev = root.val
root = root.right
return True
5. 高频考点与面试技巧
-
递归转迭代:面试官常会要求将递归解法改为迭代实现。二叉树问题中,DFS通常对应栈,BFS对应队列。
-
复杂度分析:能准确分析时间空间复杂度是加分项。例如递归解法要说明递归深度和每层时间复杂度。
-
边界条件:空树、单节点树、完全倾斜树等特殊情况要重点考虑。
-
剪枝优化:在112题路径总和中,如果找到符合条件的路径可以提前终止搜索。
-
遍历选择:
- 前序:根→左→右(适合自上而下处理)
- 中序:左→根→右(BST有序输出)
- 后序:左→右→根(适合自下而上处理)
- 层序:按深度遍历(求深度、宽度等)
我在面试候选人时发现,能清晰解释解法背后原理的候选人通常表现更好。例如在98题验证BST时,能说明为什么需要上下界而不仅是比较父节点值的候选人,往往能获得更高的评价。
