最近公共祖先(LCA)问题 笔记

最近公共祖先(转载)

1、暴力对待
    如果是二叉查找树:寻找节点u, v 的最近公共祖先  步骤

    1、如果当前结点t 大于结点u、v,说明u、v都在t 的左侧,所以它们的共同祖先必定在t 的左子树中,

         故从t 的左子树中继续查找;

    2、如果当前结点t 小于结点u、v,说明u、v都在t 的右侧,所以它们的共同祖先必定在t 的右子树中,

         故从t 的右子树中继续查找;

   3、如果当前结点t 满足 u <t < v,说明u和v分居在t 的两侧,故当前结点t 即为最近公共祖先;

   4、而如果u是v的祖先,那么返回u的父结点,同理,如果v是u的祖先,那么返回v的父结点。


示例:

public int query(Node t, Node u, Node v) {    
    int left = u.value;    
    int right = v.value;    
  
    //二叉查找树内,如果左结点大于右结点,不对,交换  
    if (left > right) {    
        int temp = left;    
        left = right;    
        right = temp;    
    }    
  
    while (true) {    
        //如果t小于u、v,往t的右子树中查找  
        if (t.value < left) {    
            t = t.right;    
  
        //如果t大于u、v,往t的左子树中查找  
        } else if (t.value > right) {    
            t = t.left;    
        } else {    
            return t.value;    
        }    
    }    
} 
二、普通的二叉树
            如果每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表。因此这个问题转换为两个单向链表的第一个公共结点。如果给出根节点,LCA问题可以用递归很快解决。而关于树的问题一般都可以转换为递归(因为树本来就是递归描述),参考代码如下:

        node getLCA(node root , node  node1, node node2)
 {
if(root==null) return null;
        if(root==node1 || root==node2) return root;
node left=getLCA(root.left, node1,node2);
        node right=getLCA(root.right , node1,node2);
        if(left != null && right != null)     
  return root;  
else if (left != null)  
    return left;  
    else if (right != null)  
        return right;  
    else   
        return null;  
} 
不论是针对普通的二叉树,还是针对二叉查找树,上面的解法有一个很大的弊端就是:如需N 次查询,则总体复杂度会扩大N 倍,故这种暴力解法仅适合一次查询,不适合多次查询。


后面的链接有更多的内容!

转载自:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/03.03.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值