leetcode 236、二叉树的最近公共祖先
题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
题解
思路
- 一般情况:目标节点的公共祖先是非目标节点,例如示例1中,这个时候我们可以使用递归,判断当前节点是否是目标节点,如果是目标节点,就返回true,如果不是就返回false,那么这个时候,我们只需要对每个节点的左右子树判断,如果左右子树都返回true,证明该节点就是公共祖先。
- 特殊情况:目标节点的公共祖先是目标节点的其中一个。例如下图,那么在这种情况下,不能只对左右子树判断,还要判断当前节点是否是目标节点且左右子树中其中一个是否返回了true。
代码
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
getRes(root,p,q);
return res;
}
// 用来存储结果
private TreeNode res;
public boolean getRes(TreeNode root, TreeNode p, TreeNode q) {
// 递归跳出
if (root == null) {
return false;
}
// 左子树的返回结果
boolean leftFlag = getRes(root.left, p, q);
// 右子树的返回结果
boolean rightFlag = getRes(root.right, p, q);
// 如果左右子树都返回true,
// 或则当前节点是目标节点其中一个且左右子树中有一个返回true,则记录结果
if ((leftFlag && rightFlag) || ((leftFlag || rightFlag) && (root == p || root == q))){
res = root;
}
// 如果当前节点是目标节点,放回true
if (root == p || root == q) {
return true;
}
// 返回左右子树中其中一个包含目标节点
return leftFlag || rightFlag;
}