在二叉树中找到最不常见的父级?

时间:2012-11-08 05:53:46

标签: algorithm tree binary-tree least-common-ancestor

这个问题可能已经被很多人提出过,但是,它有点不同。我们有一棵二叉树。你得到两个节点p& Q值。我们必须找到最不常见的父母。但是你没有指向根的根节点指针。您将获得两个内置函数:

1)BOOL same(node *p, node *q); - >如果节点相同则返回true,否则返回false。

2)node* parentNode(node *c); - >返回一个节点,该节点是当前节点的父节点。

如果节点c实际上是root,那么parentNode函数将返回NULL值。 使用我们必须的函数来找到树的最不常见的父。

2 个答案:

答案 0 :(得分:6)

第1步:使用parentNode函数从根目录中查找节点d1的距离p。类似地从根节点找到节点d2的距离q。 (例如,d2出现大于d1

第2步:移动更远的节点(其d值更大)指针d2-d1向根行进。

第3步:同时将指针pq移向root,直到它们指向同一节点并返回该节点。

基本上它就像找到两个链表的合并点。
检查以下链接: Check if two linked lists merge. If so, where?

时间复杂度:O(N)
您的代码看起来有点像:

node* LCP(node* p, node *q){
    int d1=0, d2=0;
    for(node* t= p; t; t = parentNode(p), ++d1);
    for(node* t= q; t; t = parentNode(q), ++d2);
    if(d1>d2){
        swap(d1, d2);
        swap(p, q);
    }
    for(int i=0; i<(d2-d1); ++i)
        q = parentNode(q);
    if( same(p, q)){
        return parentNode(p);
    }
    while( !same(p, q)){
        p = parentNode(p);
        q = parentNode(q);
    }
    return p;
}

答案 1 :(得分:1)

假设C ++:

node* leastCommonParent(node *p, node *q)
{
    node *pParent = parentNode(p);
    while(pParent != 0)
    {
        node *qParent = parentNode(q);
        while(qParent != 0)
        {
            if (0 == same(pParent, qParent))
                return pParent;
            qParent = parentNode(qParent);
        }
        pParent = parentNode(pParent);
    }
    return 0;
}

更新:使用递归的没有显式声明变量的版本如下。我确信它可以改进,并且可能永远不会在当前形式的生产代码中使用它。

node* qParent(node *p, node *q)
{
    if (p == 0 || q == 0)
        return 0;
    if (same(p, q) == 0)
        return p;
    return qParent(p, q->parent);
}

node* pParent(node *p, node *q)
{
    return qParent(p, q) ? qParent(p, q) : pParent(p->parent, q);
}

node * result = pParent(p, q);