公司动态

LeetCode二叉树高频题型解析与解题模板

📅 2026/8/10 8:53:14
LeetCode二叉树高频题型解析与解题模板
1. LeetCode Hot 100二叉树篇核心价值解析二叉树作为数据结构与算法领域的经典题型在LeetCode Hot 100中占比高达17%是面试考察频率最高的专题之一。我刷完所有二叉树题目后发现实际面试中80%的二叉树问题都可以归结为四种解题模板递归遍历、层次遍历、路径处理和构造二叉树。掌握这四类解法就能应对大多数二叉树面试题。从实际面试反馈来看二叉树问题主要考察三个维度基础遍历能力前中后序、变形处理能力路径求和/翻转/镜像以及综合应用能力BST验证/最近公共祖先。特别要注意那些看似简单但暗藏陷阱的题目比如平衡二叉树的判断如果不做剪枝优化很容易写出O(n²)的暴力解法。2. 二叉树核心解题框架详解2.1 递归遍历三板斧前中后序遍历是二叉树的基础但写出bug-free的代码需要特别注意递归终止条件。以LeetCode 144题为例def preorderTraversal(root): res [] def dfs(node): if not node: # 必须优先判断空节点 return res.append(node.val) # 前序位置 dfs(node.left) dfs(node.right) dfs(root) return res关键经验递归时先处理空节点能避免80%的NullPointer异常。对于迭代写法建议统一采用标记法即在访问节点时压入空指针作为标记。2.2 层次遍历的两种范式BFS模板适合求解层相关的问题如LeetCode 102但要注意每层需要单独处理def levelOrder(root): if not root: return [] queue collections.deque([root]) res [] while queue: level_size len(queue) # 关键点记录当前层节点数 level [] for _ in range(level_size): 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对于锯齿形遍历LeetCode 103只需在偶数层反转结果即可。DFS同样可以实现层次遍历通过记录depth参数来控制存储位置。2.3 路径类问题的处理技巧路径求和问题如LeetCode 112需要注意回溯时的状态恢复def hasPathSum(root, target): if not root: return False stack [(root, root.val)] while stack: node, curr_sum stack.pop() if not node.left and not node.right: # 叶子节点判断 if curr_sum target: return True if node.right: stack.append((node.right, curr_sum node.right.val)) if node.left: stack.append((node.left, curr_sum node.left.val)) return False易错点路径必须从根到叶子节点才算有效中间路径不符合要求。对于路径记录问题如LeetCode 113需要维护当前路径列表。3. 高频难题突破策略3.1 二叉树构造问题从前序与中序遍历构造二叉树LeetCode 105是典型的分治应用def buildTree(preorder, inorder): if not preorder: return None root_val preorder[0] root TreeNode(root_val) idx inorder.index(root_val) # 找到根节点在中序的位置 root.left buildTree(preorder[1:idx1], inorder[:idx]) root.right buildTree(preorder[idx1:], inorder[idx1:]) return root优化点可以先用哈希表存储中序遍历的值到索引的映射将时间复杂度从O(n²)降到O(n)。3.2 二叉搜索树验证验证BSTLeetCode 98看似简单但通过率仅26%常见错误是只检查当前节点与左右子节点的关系def isValidBST(root): def helper(node, lowerfloat(-inf), upperfloat(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)关键理解BST要求整个左子树都小于根节点整个右子树都大于根节点需要传递上下界参数。3.3 最近公共祖先问题LCA问题LeetCode 236的递归解法非常精妙def lowestCommonAncestor(root, p, q): if not root or root p or root q: return root left lowestCommonAncestor(root.left, p, q) right lowestCommonAncestor(root.right, p, q) if left and right: # 左右子树各找到一个目标节点 return root return left if left else right # 只在单侧找到则返回该侧结果这个解法的时间复杂度是O(n)空间复杂度O(h)。对于BST中的LCALeetCode 235可以利用BST性质进行剪枝。4. 二叉树优化技巧与面试陷阱4.1 时间复杂度优化实战以计算二叉树直径LeetCode 543为例暴力解法会对每个节点计算左右子树高度导致O(n²)时间复杂度。优化方案是在计算高度的同时记录直径def diameterOfBinaryTree(root): self.diameter 0 def depth(node): if not node: return 0 left depth(node.left) right depth(node.right) self.diameter max(self.diameter, left right) return max(left, right) 1 depth(root) return self.diameter4.2 空间复杂度优化方案Morris遍历可以在O(1)空间复杂度下实现中序遍历def inorderTraversal(root): res [] curr root while curr: if not curr.left: res.append(curr.val) curr curr.right else: pre curr.left while pre.right and pre.right ! curr: pre pre.right if not pre.right: pre.right curr curr curr.left else: pre.right None res.append(curr.val) curr curr.right return res这种算法会临时修改树结构适合内存严格受限的场景。4.3 面试常见陷阱题翻转二叉树LeetCode 226看似简单但如果不使用临时变量直接交换左右子树会导致错误# 正确写法 def invertTree(root): if root: root.left, root.right invertTree(root.right), invertTree(root.left) return root # 错误写法会导致右子树被覆盖 def invertTree_wrong(root): if root: root.left invertTree(root.right) root.right invertTree(root.left) # 此时root.left已经被修改 return root对称二叉树LeetCode 101也容易陷入只比较左右子节点值的陷阱实际上需要递归比较整棵子树。5. 二叉树刷题进阶路线5.1 必刷题目分类训练按照难度梯度建议的刷题顺序基础遍历144、94、145、102属性判断101、104、110、111路径问题112、113、124、257构造转换105、106、108、114祖先问题235、236序列化297特殊结构116、1175.2 二叉树与其他数据结构的结合当二叉树与哈希表结合时如LeetCode 437路径总和III可以用前缀和优化def pathSum(root, target): from collections import defaultdict prefix defaultdict(int) prefix[0] 1 self.count 0 def dfs(node, curr_sum): if not node: return curr_sum node.val self.count prefix[curr_sum - target] prefix[curr_sum] 1 dfs(node.left, curr_sum) dfs(node.right, curr_sum) prefix[curr_sum] - 1 # 回溯 dfs(root, 0) return self.count5.3 二叉树在工程中的应用实例在数据库索引设计中B树作为二叉树的扩展形式广泛应用在游戏开发中四叉树/八叉树用于空间分区在编译原理中语法分析树是二叉树的变种。理解这些应用场景能帮助更好地掌握二叉树的核心思想。