描述
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
要求:空间复杂度 O(n),时间复杂度 O(n)
注:本题保证二叉树中每个节点的val值均不相同。
如当输入[3,5,1,6,2,0,8,#,#,7,4],5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}
如下图所示:
所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。
示例1
输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
复制
返回值:
3
以下是牛客某大佬的解法
方法:递归
分析可知,对于节点 o1, o2 的最近公共祖先,只存在三种情况:
-
1、o1 ,o2 分别位于root的左右子树上
-
2、o1 = root, 且 o2 位于root的左子树/右子树中
-
3、o2 = root, 且 o1 位于root的左子树/右子树中
于是,可以通过递归解决本题
递归情况:
1.当到达空节点(既叶子节点的子节点)时,直接返回空
2.当root等于 o1 或 o2 时,返回root
3.若不为1, 2中情况,说明需要继续处理:
对左子树进行递归,返回值记为 t1
对右子树进行递归,返回值记位 t2
t1 ,t2 存在以下几种情况:
①. 当t1, t2都为空时,说明root的左右子树中都不存在o1, o2, 返回空
②. 当t1为空且t2不为空时,说明左子树找不到 o1, o2,所以返回 t2
③. 当t2为空且t1不为空时,说明右子树找不到 o1, o2,所以返回 t1
④. 当t1, t2都不为空时,说明o1, o2分别位于root的左右子树中,既root为答案,返回root
核心代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root ==p || root==q) return root;
//后序遍历
//左
TreeNode t1 = lowestCommonAncestor(root.left,p,q);
//右
TreeNode t2 = lowestCommonAncestor(root.right,p,q);
//中
if(t1 !=null && t2 !=null) {
return root;
}
else if(t1 !=null && t2 == null){
return t1;
}
else if(t1 ==null && t2 != null) {
return t2;
}
else{
return null;
}
}
}
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
TreeNode node = fun( root,o1,o2);
return node.val;
}
public static TreeNode fun(TreeNode root, int o1, int o2) {
// write code here
if(root == null) return null;
if(root.val==o1 || root.val==o2) return root;
TreeNode t1=fun(root.left,o1,o2) ;
TreeNode t2=fun(root.right,o1,o2);
//1、如果t1为空,说明这两个节点在root结点的右子树上,我们只需要返回右子树查找的结果t2即可
if(t1==null) return t2;
//2、同理
if(t2==null) return t1;
//3、如果t1和t2都不为空,说明这两个节点一个在root的左子树上一个在root的右子树上,
//我们只需要返回cur结点即可
return root;
}
}