538 字
3 分钟
二叉树的最近公共祖先

题目描述#

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

解题思路#

  1. 递归搜索
    • 后序遍历二叉树(左→右→根)
    • 若当前节点是 p 或 q,返回该节点
    • 递归搜索左右子树
  2. 结果合并
    • 左右子树均找到节点 → 当前节点为 LCA
    • 仅左子树找到 → 返回左子树结果
    • 仅右子树找到 → 返回右子树结果
  3. 基准情况
    • 空节点返回 null
    • 找到 p/q 直接返回

关键洞察#

  1. 后序优势
    • 先处理子树再处理根节点
    • 自然获取子树搜索结果
  2. 短路优化
    • 当找到 LCA 时提前终止递归
    • 避免无效子树搜索
  3. 状态传递
    • 非空返回值表示子树存在目标节点
    • 双非空返回值确定 LCA 位置
  4. 单节点处理
    • 当 p/q 是祖先时自动处理
    • 无需特殊边界判断

复杂度分析#

指标说明
时间复杂度O(n):每个节点最多访问一次
空间复杂度O(h):递归栈深度(h为树高,最坏O(n))

代码实现#

var lowestCommonAncestor = function (rootpq) {
  if (!root || root === p || root === q) return root;
  const left = lowestCommonAncestor(root.left, p, q);
  const right = lowestCommonAncestor(root.right, p, q);
  if (left && right) return root;
  return left || right;
};

实际应用场景#

  1. 家谱分析:查找两人最近共同祖先`
  2. 文件系统:查找两个文件最近公共目录`
  3. 版本控制:查找代码提交的最近共同基线`
  4. 网络路由:查找两个节点的最近公共路由器`

相似题目#

二叉树的最近公共祖先
https://website-truelovings-projects.vercel.app/posts/algorithms/二叉树的最近公共祖先/
作者
欢迎来到StarSky的网站!
发布于
2025-08-06
许可协议
CC BY-NC-SA 4.0