1. 题目

2. 解法
解题思路
- 我们要找到两个指定节点的最近公共祖先,也就是说,我们要找到一个节点,它是两个指定节点的祖先,而且它的深度尽可能大。
- 为了找到这样的节点,我们可以从根节点开始,递归地遍历二叉树,判断每个节点是否满足这个条件。
- 如果一个节点满足这个条件,那么它必须同时满足以下两个子条件:
- 它本身是两个指定节点之一,或者它的左子树和右子树分别包含两个指定节点。
- 它的左子树和右子树中没有其他节点满足这个条件,也就是说,它是最深的满足条件的节点。
- 因此,我们可以定义一个递归函数,它接受一个根节点和两个目标节点作为参数,返回这三个节点的最近公共祖先。如果不存在这样的祖先,就返回空。
- 在递归函数中,我们首先判断根节点是否为空,或者是否等于其中一个目标节点。如果是,就直接返回根节点,因为它就是最近公共祖先。
- 然后,我们递归地调用这个函数,分别对根节点的左子树和右子树进行遍历,得到两个返回值,分别表示左子树和右子树中是否存在目标节点。
- 最后,我们根据左右子树的返回值来判断最近公共祖先是谁。有三种情况:
- 如果左右子树都不为空,说明两个目标节点分别在根节点的两侧,那么根节点就是最近公共祖先。
- 如果左子树为空,说明两个目标节点都在右子树中,那么右子树的返回值就是最近公共祖先。
- 如果右子树为空,说明两个目标节点都在左子树中,那么左子树的返回值就是最近公共祖先。
这样,我们就可以通过递归遍历二叉树,找到两个指定节点的最近公共祖先了。
具体实现
// 定义二叉树节点
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
// 解决方法
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;
// 如果左子树为空,返回右子树
if (left == null) return right;
// 如果右子树为空,返回左子树
return left;
}
}
3. 总结
浙公网安备 33010602011771号