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

输入:root=[3,5,1,6,2,0,8,null,null,7,4],p=5,q=1
输出:3
解释:节点1和节点5的最近公共祖先是节点3.
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 1. 递归终止条件(Base Case)
// 如果当前节点为空,或者当前节点就是我们要找的 p 或 q,直接返回当前节点
if (root == p || root == q || root == null) return root;
// 2. 递归调用(Drill Down)
// 去左子树找 p 和 q
TreeNode left = lowestCommonAncestor(root.left, p, q);
// 去右子树找 p 和 q
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 3. 处理返回值(Process Logic)
// 情况 A: 左右子树都有返回值(都不为空)
// 说明 p 和 q 分别位于当前节点的左侧和右侧,那么当前节点 root 就是最近公共祖先
if (left != null && right != null) return root;
// 情况 B: 左子树没找到(为空),返回右子树的结果
// 说明 p 和 q 都在右子树中(或者都没找到)
if (left == null) return right;
// 情况 C: 右子树没找到(为空),返回左子树的结果
// 说明 p 和 q 都在左子树中
return left;
}
题解:root:当前树的根节点;p:要寻找的第一个节点;q:要寻找的第二个节点。返回值类型是TreeNode,表示找到的最近公共祖先节点。
如果当前节点是否为p或q,或者是否为空节点。则返回root节点,因为我们找到了其中一个节点。否则返回null,表示没有找到任何节点。
递归调用分别搜索左子树和右子树,结果存储在left和right中。
如果left和right都不为null,这意味p和q分别在root的左右子树中,因此当前节点是它们的最近公共祖先。
如果left为null,说明p和q都不在左子树中,那么返回right,即右子树中的结果。
如果right为null,说明p和q都不在右子树中,那么返回left,即左子树中的结果。
时间复杂度为O(N),其中N是节点数,空间复杂度为O(H),H是树的高度。






Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.
Is there anything you don’t understand?
I’ve added the relevant annotations. Do you think you’ll be able to understand it this time?