- 情况一:root未知,但是每个节点都有parent指针
解决方法是求出linkedList A的长度lengthA, linkedList B的长度LengthB。然后让长的那个链表走过abs(lengthA-lengthB)步之后,齐头并进,相遇的节点就是最近公共父节点。
template <class T>
int getLength(BinaryTreeNode<T>* pNode)
{
int length = 0;
BinaryTreeNode<T>* pTemp = pNode;
while (pTemp)
{
length++ ;
pTemp = pTemp->pParent;
}
return length;
}
template <class T>
BinaryTreeNode<T>* findLCACase1(BinaryTreeNode<T>* pNode1, BinaryTreeNode<T>* pNode2)
{
int length1 = getLength(pNode1);
int length2 = getLength(pNode2);
// skip the abs(length1-length2)
BinaryTreeNode<T>* pIter1 = NULL;
BinaryTreeNode<T>* pIter2 = NULL;
int k = 0;
if (length1>=length2) {
bstNode* pTemp = pNode1;
while (k++ < length1-length2) {
pTemp = pTemp->pParent;
}
pIter1 = pTemp;
pIter2 = pNode2;
} else {
BinaryTreeNode* pTemp = pNode1;
while (k++ < length2-length1) {
pTemp = pTemp->pParent;
}
pIter1 = pNode1;
pIter2 = pTemp;
}
while (pIter1 && pIter2 && pIter1!= pIter2) {
pIter1 = pIter1->pParent;
pIter2 = pIter2->pParent;
}
return pIter1;
}
- 情况二:节点只有left/right,没有parent指针,root已知
template <class T>
bool nodePath(BinaryTreeNode<T>* pRoot, int value, vector<BinaryTreeNode<T>*>& path)
{
if (pRoot==NULL)
return false;
if (pRoot->data != value) {
if (nodePath(pRoot->pLeft, value, path)) {
path.push_back(pRoot);
return true;
} else if (nodePath(pRoot->pRight, value, path)) {
path.push_back(pRoot);
return true;
} else
return false;
} else {
path.push_back(pRoot);
return true;
}
}
template <class T>
BinaryTreeNode<T>* findLCACase2(BinaryTreeNode<T>* pNode, int value1, int value2)
{
std::vector<BinaryTreeNode<T>*> path1;
std::vector<BinaryTreeNode<T>*> path2;
bool find = false;
find |= nodePath(pNode, value1, path1);
find &= nodePath(pNode, value2, path2);
BinaryTreeNode<T>* pReturn = NULL;
if (find) {
int minSize = path1.size()>path2.size()?path2.size():path1.size();
int it1 = path1.size()- minSize;
int it2 = path2.size()- minSize;
for ( ; it1<path1.size(), it2<path2.size(); it1++, it2++) {
if (path1[it1]==path2[it2]) {
pReturn = path1[it1];
break;
}
}
}
return pReturn;
}
- 情况三: 二叉树是个二叉查找树,且root和两个节点的值(a, b)已知
BinaryTreeNode<T>* findLCACase3(BinaryTreeNode<T>* pNode, int value1, int value2)
{
BinaryTreeNode<T>* pTemp = pNode;
while (pTemp) {
if (pTemp->data>value1 && pTemp->data>value2)
pTemp = pTemp->pLeft;
else if(pTemp->data<value1 && pTemp->data<value2)
pTemp = pTemp->pRight;
else
return pTemp;
}
return NULL;
}