给一棵二叉树和二叉树中的两个节点,找到这两个节点的最近公共祖先 LCA。两个节点的最近公共祖先,是指两个节点的所有父亲节点中(包括这两个节点),离这两个节点最近的公共的节点。返回 null 如果两个节点在这棵树上不存在最近公共祖先的话。
注意事项
这两个节点未必都在这棵树上出现。
样例
给出下面这棵树:
4
/ \
3 7
/ \
5 6
LCA(3, 5) = 4
LCA(5, 6) = 7
LCA(6, 7) = 7
LCA(5, 8) = null
PS
A 和 B 不一定在树中存在,需要定义纪录存在与否的变量,如果不存在,无需去寻找公共祖先
代码
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
// A 结点是否存在, B 结点是否存在, A 和 B 的公共祖先
class ResultType {
public boolean a_exist, b_exist;
public TreeNode node;
ResultType(boolean a, boolean b, TreeNode n) {
a_exist = a;
b_exist = b;
node = n;
}
}
public class Solution {
/**
* @param root The root of the binary tree.
* @param A and B two nodes
* @return: Return the LCA of the two nodes.
*/
public TreeNode lowestCommonAncestor3(TreeNode root, TreeNode A, TreeNode B) {
ResultType rt = helper(root, A, B);
// 若 A 和 B 有一个不存在,则它们在二叉树上没有公共祖先
if (rt.a_exist && rt.b_exist) {
return rt.node;
}
return null;
}
public ResultType helper(TreeNode root, TreeNode A, TreeNode B) {
if (root == null) {
return new ResultType(false, false, null);
}
ResultType left_rt = helper(root.left, A, B);
ResultType right_rt = helper(root.right, A, B);
// 当前 root 对应的 a_exist 和 b_exist 的布尔值
boolean a_exist = left_rt.a_exist || right_rt.a_exist || root == A;
boolean b_exist = left_rt.b_exist || right_rt.b_exist || root == B;
// 确定公共祖先的值
// 要考虑到根结点是目标结点本身的情况
if (root == A || root == B) {
return new ResultType(a_exist, b_exist, root);
}
if (left_rt.node != null && right_rt.node != null) {
return new ResultType(a_exist, b_exist, root);
}
if (left_rt.node != null) {
return new ResultType(a_exist, b_exist, left_rt.node);
}
if (right_rt.node != null) {
return new ResultType(a_exist, b_exist, right_rt.node);
}
return new ResultType(a_exist, b_exist, null);
}
}