NC102 在二叉树中找到两个节点的最近公共祖先

描述
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值