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

Algorithm 在二叉树中查找最不常见的父级?,algorithm,tree,binary-tree,least-common-ancestor,Algorithm,Tree,Binary Tree,Least Common Ancestor,这个问题可能会被很多人问到,但它有点不同。我们有一棵二叉树。给你两个节点p&q。我们必须找到最不常见的父母。但是您没有指向根的根节点指针。我们为您提供了两个内置函数,它们是: 1) BOOL相同(节点*p,节点*q)->如果节点相同,则返回true,否则返回false 2) node*parentNode(node*c)->返回当前节点的父节点 如果节点c实际上是根节点,那么parentNode函数将返回一个NULL值。 使用函数我们必须找到树的最不常见的父节点。步骤1:使用parentNode

这个问题可能会被很多人问到,但它有点不同。我们有一棵二叉树。给你两个节点p&q。我们必须找到最不常见的父母。但是您没有指向根的根节点指针。我们为您提供了两个内置函数,它们是:

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

2)
node*parentNode(node*c)->返回当前节点的父节点

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

步骤1:使用
parentNode
函数找到节点
p
到根节点的距离
d1
。类似地,从根查找节点
q
的距离
d2
。(比如说,
d2
出来的值大于
d1


步骤2:将更远的节点(其d值更大)指针
d2-d1
移向根

步骤3:同时将指针
p
q
向根移动,直到它们指向同一节点并返回该节点。

基本上,这就像找到两个链表的合并点一样
检查以下链接:

时间复杂度:O(N)
您的代码看起来大致如下:

node*LCP(node*p,node*q){
int d1=0,d2=0;
对于(node*t=p;t;t=parentNode(p),+d1);
对于(node*t=q;t;t=parentNode(q),+d2);
如果(d1>d2){
掉期(首被告、次被告);
swap(p,q);
}
对于(int i=0;i假设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);

好的..我会接受答案,但是否仍有不使用临时节点的方法。谢谢。函数只使用指向节点的指针,因此没有创建节点的副本,这就是为什么我不能完全确定为什么临时节点会成为问题。根据需要,可以不使用递归的指针。我的意思是你不应该使用额外的变量或指针来保存地址。原因是这个问题是在采访中问朋友的。据说他不应该使用任何临时指针或变量。有一种情况下,当
p
q
(甚至
p==q
)的祖先时,这会失败,您的算法将返回
p
最不常见的父项是
p->parent
。我假设其中一个不是自己的父项。啊!是的,您是对的。我现在更新了代码以处理边缘情况。
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);