原题
树与图中等1 种解法

#236二叉树的最近公共祖先

在普通二叉树中寻找两个给定节点的最近公共祖先。

#二叉树#深度优先搜索#后序遍历

原题

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

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

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:

输入:root = [1,2], p = 1, q = 2
输出:1

提示:

  • 树中节点数目在范围 [2, 105] 内。
  • -109 <= Node.val <= 109
  • 所有 Node.val 互不相同
  • p != q
  • pq 均存在于给定的二叉树中。

查看原题

解题主线

  1. 后序返回值表示当前子树是否找到了 p 或 q;左右均非空时当前根就是答案。

解法 1:后序递归汇总

分别向左右查找;两侧都有结果返回根,否则向上传递非空侧。

  • 时间复杂度: O(n)

  • 空间复杂度: O(h)

JAVA
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 返回值表示当前子树中找到的 p、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;
        return left != null ? left : right;
    }
}

边界与易错点

  • 命中 p 或 q 时应立即返回当前节点,使祖先能够汇总两侧结果。
  • 两个来源中的同质实现只保留一次。

整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

  • leetcode/src/main/java/tree/Q235_236_lowestCommonAncestor.java
  • leetcode/src/main/java/tree/Q236_lowestCommonAncestor.java