首页 > 试题广场 >

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

[编程题]在二叉树中找到两个节点的最近公共祖先
  • 热度指数:163149 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足 , 节点值val满足区间 [0,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
示例2

输入

{3,5,1,6,2,0,8,#,#,7,4},2,7

输出

2

说明:本题目包含复杂数据结构TreeNode,点此查看相关信息
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    // write code here
    //与JZ68的区别,二叉树不同于二叉搜索树,值没有规律
    if(!root)return
    if(root.val==o1) return root.val
    if(root.val==o2) return root.val
    let left=lowestCommonAncestor(root.left,o1,o2)
    let right=lowestCommonAncestor(root.right,o1,o2)
    if(left&&right) return root.val
    if(left) return left
    if(right) return right
}

发表于 2022-08-03 08:42:05 回复(0)
/*
 * function TreeNode(x) {
 *   this.val = x;
 *   this.left = null;
 *   this.right = null;
 * }
 */

/**
 * 
 * @param root TreeNode类 
 * @param o1 int整型 
 * @param o2 int整型 
 * @return int整型
 */
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
   if(!root) return -1
   if(root.val===o1 || root.val == o2){
       return root.val
   }
    let left = lowestCommonAncestor(root.left,o1,o2)
    let right = lowestCommonAncestor(root.right,o1,o2)
//     如果在左子树中o1和o2都没找到,则肯定在其右子树中,右子树遍历到的那个节点就是最近公共祖先
    if(left == -1){
        return right
    }else if(right == -1){
// 同样如果在右子树中没找到o1和o2,肯定在其左子树
        return left
    }else{
//         两个都找到了,说明在root的两侧,那么root就是祖先
        return root.val
    }
   
}
module.exports = {
    lowestCommonAncestor : lowestCommonAncestor
};

发表于 2022-01-23 14:54:16 回复(0)
同样的JavaScript代码力扣上成功跑过,这上面不通过,真扯
发表于 2021-11-08 14:46:40 回复(0)
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    // write code here
    let path1=getChildPath(root,o1);
    let path2=getChildPath(root,o2);
    path1.reverse();
    let r=path1.filter(function(val){
        return path2.indexOf(val)>=0;
    });
    return r[0];
}

function getChildPath(root,val){
    if(root.val==val ){
        return [val];
    }
    let pathsChild=null;
    if(root.left){
        try{
            pathsChild=getChildPath(root.left,val);
        }catch(err){
        }
    }
    if(root.right){
        try{
            pathsChild=getChildPath(root.right,val);
        }catch(err){
        }
    }
    
    if(!pathsChild){
        throw "error";
    }
    return [root.val,...pathsChild];
}


module.exports = {
    lowestCommonAncestor : lowestCommonAncestor
};
发表于 2021-10-10 13:28:15 回复(0)
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    if(!root) return null
//     找到跟o1或o2相等的值返回
    if(root.val == o1 || root.val == o2) return root.val
//     遍历左子树,找到值返回
    let left = lowestCommonAncestor(root.left, o1 ,o2)
//     遍历右子树,找到值返回
    let right = lowestCommonAncestor(root.right, o1 ,o2)
//     此时左子树找不到值,那就说明值都在右子树,第一个被找到的值就是公共祖先
    if(!left) return right
//     此时右子树找不到值,那就说明值都在左子树,第一个被找到的值就是公共祖先
    if(!right) return left
//     此时左右子树都找到值了,所以他们的共同祖先就是根的值
    return root.val
}
发表于 2021-10-02 12:47:09 回复(0)
function lowestCommonAncestor(root, o1, o2) {
    // write code here
    var dfs = function (root, p, q) {
        if (root == null || root.val == p || root.val == q) {
            return root;
        }
        var left = dfs(root.left, p, q);
        var right = dfs(root.right, p, q);
        if (left && right) {
            return root;
        } else {
            return left ? left : right;
        }
    };
    var res = dfs(root, o1, o2);
    return res.val;
}
参考   https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-ii-er-cha-shu-de-zui-jin-gong-gon-7/
发表于 2021-07-19 12:15:25 回复(0)
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    if (!root) return NaN;
    if ([o1, o2].includes(root.val)) return root.val;
    const left = lowestCommonAncestor(root.left, o1, o2);
    const right = lowestCommonAncestor(root.right, o1, o2);
    if (!left) return right;
    if (!right) return left;
    if (!left && !right) return NaN;
    return root.val;
}

编辑于 2021-04-14 20:47:25 回复(0)
/*
 * function TreeNode(x) {
 *   this.val = x;
 *   this.left = null;
 *   this.right = null;
 * }
 */

/**
 * 
 * @param root TreeNode类 
 * @param o1 int整型 
 * @param o2 int整型 
 * @return int整型
 */
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    // write code here
    if(root===null || root.val== o1 || root.val== o2){ //单根、没有左右子树
        return root
    }
    //递归获取左右子树
    const left = lowestCommonAncestor( root.left ,  o1 ,  o2 );
    const right = lowestCommonAncestor( root.right ,  o1 ,  o2 );
    //左右子树都不为空,则返回根节点
    if(left != null && right != null){
        return root.val
    }
    //左右子树其中一个不为空,则放回相应子树的查找结果
    return left != null ? left : right
    //三元运算符的表达式:
    //(expression1)  ?  (expression2)  :  (expression3)
    //在  expression1  求值为  true  时的值为  expression2  ,在expression1  求值是  false  时的值为  expression3

//     if(left==null){
//         return right;
//     }else if(right==null){
//         return left;
//     }else{
//         return root.val;
//     }
}
module.exports = {
    lowestCommonAncestor : lowestCommonAncestor
};


发表于 2021-03-01 18:11:06 回复(0)
function lowestCommonAncestor( root ,  o1 ,  o2 ) {
    // 遇到叶子节点返回
    if (root === null) {
        return null
    }
    // 如果p或q为根节点,则p或q为最近公共祖先
    if (root.val === o1 || root.val === o2) {
        return root.val
    }
    // 在左子树寻找p和q的最近公共祖先
    const leftRes = lowestCommonAncestor(root.left, o1, o2)
    // 在右子树寻找q和q的最近公共祖先
    const rightRes = lowestCommonAncestor(root.right, o1, o2)
    // 如果p和q分属两侧,则根节点为最近公共祖先
    if (leftRes && rightRes) {
        return root.val
    }
    // 如果左子树有值,则最近公共祖先在左子树,否则,在右子树
    return leftRes ? leftRes : rightRes
}

编辑于 2020-11-22 23:24:00 回复(0)

问题信息

难度:
10条回答 9076浏览

热门推荐

通过挑战的用户

查看代码