import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
public class Info {
public boolean findP;
public boolean findQ;
public int lowestCommonAncestor;
public Info () {
this.findP = false;
this.findQ = false;
this.lowestCommonAncestor = -1;
}
public Info (boolean findP, boolean findQ, int lowestCommonAncestor) {
this.findP = findP;
this.findQ = findQ;
this.lowestCommonAncestor = lowestCommonAncestor;
}
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
// 根据左程云老师讲的【二叉树递归套路】,先弄明白三件事
// 1.我要干什么:
// 获知【左子树】中【有无p,q或最小公共祖先】
// 获知【右子树】中【有无p,q或最小公共祖先】
// 2.我需要什么信息:
// 综上所述,我需要左右子树的【有无p,q或最小公共祖先】
// 3.我如何利用两个子树的信息加工出来我的信息:
// 将有无p和q取或;若左右子树已经有lowestCommonAncestor了,则传递,反之则赋值
// 调用递归函数求解
return process(root, o1, o2).lowestCommonAncestor;
}
public Info process(TreeNode root, int p, int q) {
// 递归出口
if (root == null) {
// 到底返回
return new Info();
}
// 从左右子树获取信息
Info leftInfo = process(root.left, p, q);
Info rightInfo = process(root.right, p, q);
// 根据获取到的信息加工出自己的信息
// 三者满足其一即可为true
boolean findP = leftInfo.findP || rightInfo.findP || root.val == p;
boolean findQ = leftInfo.findQ || rightInfo.findQ || root.val == q;
if (findP && findQ) {
// 如果本子树已经同时发现P和Q了
if (leftInfo.lowestCommonAncestor == -1 && rightInfo.lowestCommonAncestor == -1) {
// 同时两个子树都不曾同时发现P和Q
// 说明本结点才是P和Q的最近公共祖先节点
return new Info(findP, findQ, root.val);
} else {
// 同时两个子树中已经有一个找到最近公共祖先节点了
// 将它们中非-1的那个传递下去
int val = (leftInfo.lowestCommonAncestor != -1) ? leftInfo.lowestCommonAncestor : rightInfo.lowestCommonAncestor;
return new Info(findP, findQ, val);
}
}
// 还没同时发现P和Q,将当前状态向上传递
return new Info(findP, findQ, -1);
}
}