💨题目链接:
💨题目描述:
💨递归求解:
采用前序遍历的思路,创建 left 和 right 俩个结点作为左树递归和右树递归的返回值,返回时做出判断即可。
判断条件:
- 当前 root == null 时,应返回 null,代表当前这课子树没有找到 p 或者 q。
- 首先应该判断 root 是否是 p 或者 q 这俩个结点,如果是,返回 root 本身。
- 当 left 和 right 都为 null 时,代表当前 root 为根结点的这课树他的左右子树均未找到 p 或者 q,应返回 null。
- 当 left 或者 right 一方为 null 时,一方不为 null 时代表着为 null 的那棵树未找到 p 或者 q,不为null 的那个树找到了,应该返回不为 null 的那颗树的根结点,例如 right 不为null ,应当返回 right ,可能是 right 本事就是 p 或者 q,也有可能是 right 为根结点他的子树里有 p 或者 q。
- 如果 left 和 right 都不为 null 时,直接返回 root 即可,因为当前情况下,root 的左子树 找到了 p 或者 q 一方,右子树也找到了 p 或者 q 一方,那 root 不就是他俩的最近公共祖先吗。
🐸当前存在的疑问:
当 p 本身是 q 的最近公共祖先会不会发生错误❓
答案是不会,根据判断条件2,如果先找到 q 结点,当找到 p 结点时,会直接返回这个结点 root 本身,后序根据判断条件4,一方为 null,一方不为 null,不为 null 的也就是我们的 p 结点,将会一直返回到递归结束。
代码:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) {
return null;
}
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
//相等就返回root
if(root == p || root == q) {
return root;
}
//都为null,代表子树没有p,q
if(left == null && right == null) {
return null;
}
//一方为空,返回另一方找到的
if(left == null) {
return right;
}
if(right == null) {
return left;
}
//都不为null,代表左右树都找到了,那么root就是他俩的公共祖先
return root;
}