树与图中等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 != qp和q均存在于给定的二叉树中。
解题主线
- 后序返回值表示当前子树是否找到了 p 或 q;左右均非空时当前根就是答案。
解法 1:后序递归汇总
分别向左右查找;两侧都有结果返回根,否则向上传递非空侧。
-
时间复杂度: O(n)
-
空间复杂度: O(h)
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.javaleetcode/src/main/java/tree/Q236_lowestCommonAncestor.java