求二叉树两个节点的最近祖先节点
最近在看一些面试题,又遇到这个题了。我有印象我看到过,不过对解题思路就模模糊糊了,只记得很坑。所以这次拿出来,重新梳理一下,以备录。
这次是在CrackCode上面看到的,原题描述如下:
Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
应该不需要翻译吧,关键在于避免使用额外的空间存储信息;而且该树不是BST。
看来该题的限制条件比较多,先来看看没有限制的条件。
- 如果该树是BST,如何做?
struct Node
{
int key;
Node *lchild, *rchild, *parent;
};
Node* find_LCA_BST(Node *head, Node *q, Node *p)
{
if(head == NULL || q == NULL || q == NULL) return NULL;
int left,right;
if(q->key >= p->key)
{
right = q->key;
left = p->key;
}else
{
right = p->key;
left = q->key;
}
while(head)
{
if(right < head->key)
head = head->lchild;
else if(left > head->key)
head = head->rchild;
else
return head;
}
}
- 如果该树不是一个BST,但是可以用额外内存空间
struct Node
{
int key;
Node *lchild, *rchild, *parent;
};
Node* find_LCA_with_other_memory(Node *p, Node *q)
{
if(p == NULL || q == NULL) return NULL;
map<Node* bool> m;
while(p)
{
m[p] = true;
p = p->parent;
}
while(q && !m[q])
{
q = q->parent;
}
return q;
}
- 如果该节点中不包含指向父节点的指针
struct Node
{
int key;
Node *lchild, *rchild, *parent;
};
bool find_node_path(Node* head, Node* p, vector<Node*> &path)
{
if(head == NULL) return false;
if(p == head)
{
path.push_back(head);
return true;
}
else if(find_node_path(head->lchild, p, path))
{
path.push_back(head->lchild);
return true;
}
else if(find_node_path(head->rchild, p, path))
{
path.push_back(head->rchild);
return true;
}
return false;
}
Node* find_LCA_without_parent(Node* head, Node* p, Node*q)
{
vector<Node*> path1, path2;
bool find = find_node_path(head, p, path1);
find &= find_node_path(head, q, path2);
if(!find) return NULL;
Node* res = NULL;
int minLength = path1.size() > path2.size()?path2.size():path1.size();
//寻找两个相交链表的第一个公共节点
for(int i = path1.size()-minLength, j = path2.size()-minLength;i<path1.size() && j<path2.size();i++,j++)
{
if(path1[i] == path2[j])
res = path1[i];
}
return res;
}
今天就先更新到这里。这个题目的变化实在是太多了,我还得在网上找找其他更好的方法。有一些比较复杂,以后理解了再补上,留个坑

浙公网安备 33010602011771号