题目描述:输入两个树节点,找出它们的最低公共祖先。这是一棵普通树而且没有指向父节点的指针。
解题思路:
- 使用了两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。
- 首先得到一条从根节点到树中某一结点的路径,借助前序遍历,VLR。
- 找出两个输入节点的两条路径。
- 找到这两条路径的公共结点,便是输入两个树节点的最低公共祖先。
函数实现:
//第一步:得到输入节点路径
bool GetNodePath(TreeNode *pRoot, TreeNode *pNode, list<TreeNode*> &path){
if(pRoot == pNode)
return true;
//前序遍历
path.push_back(pRoot);
bool found = false;
std::vector<TreeNode*>::iterator i = pRoot->m_vChildren.begin();
while(!found && i < pRoot->m_vChildren.end()){
found = GetNodePath(*i, pNode, path);
++i;
}
if(!found)
path.pop_back();
return found;
}
//第二步:得到公共节点
TreeNode* GetLastCommonNode(const list<TreeNode*> &path1, const list<TreeNode*> &path2){
list<TreeNode*>::iterator iterator1 = path1.begin();
list<TreeNode*>::iterator iterator2 = path2.begin();
TreeNode *pLast = NULL;
while(iterator1 != path1.end() && iterator2 != path2.end()){
if(*iterator1 == *iterator2)
pLast = *iterator1;
++iterator1;
++iterator2;
}
return pLast;
}
//第三步:主函数
TreeNode* GetLastCommonParent(TreeNode *pRoot, TreeNode *pNode1, TreeNode *pNode2){
if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)
return NULL;
//节点1的路径
list<TreeNode*> path1;
GetLastCommonNode(pRoot, pNode1, path1);
//节点2的路径
list<TreeNode*> path2;
GetLastCommonNode(pRoot, pNode2, path2);
return GetLastCommonParent(path1, path2);
}