题目
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
思路
最近公共祖先只有三种情况,前面分析同剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
考虑通过递归对二叉树进行后序遍历,当遇到节点 p
或 q
时返回。从底至顶回溯:
(1)当节点 p,q
在节点 root
的异侧(分别在左右子树时)时,节点 root
即为最近公共祖先,则向上返回 root
。
(2)当节点 p,q
在节点 root
的同侧(都在左/右子树时)时,先找到谁,谁就是最近公共祖先,就返回谁
java代码如下:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q){
if(root == null || root == p || root == q){//找到p、q或者空节点就返回
return root;
}
//后序遍历
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left == null && right == null){//如果未找到节点p或q
return null;
}else if(left == null && right != null){//若同在右侧,则先找到谁返回谁
return right;
}else if(left != null && right == null){//若同在左侧,则先找到谁返回谁
return left;
}else {
return root;//当 left和 right均不为空时,说明 p、q节点分别在 root异侧, 最近公共祖先即为 root
}
}
}