题目描述
输入两个二叉树结点,求它们的最低公共祖先。
算法分析
用两个链表分别保存从根节点到输入的两个节点的路径,然后把问题转换成两个链表的最后公共节点。
提交代码:
class Solution {
public:
const TreeNode* getLastCommonParent(const TreeNode* pRoot,
const TreeNode* pNode1, const TreeNode* pNode2)
{
if (!pRoot || !pNode1 || !pNode2)
return nullptr;
list<const TreeNode*> path1, path2;
getNodePath(pRoot, pNode1, path1);
getNodePath(pRoot, pNode2, path2);
return getLastCommonNode(path1, path2);
}
bool getNodePath(const TreeNode* pRoot, const TreeNode* pNode,
list<const TreeNode*> &path)
{
if (pRoot == pNode)
return true;
bool found = false;
path.push_back(pRoot);
if (pRoot->left)
found = getNodePath(pRoot->left, pNode, path);
if (!found && pRoot->right)
found = getNodePath(pRoot->right, pNode, path);
if(!found)
path.pop_back();
return found;
}
const TreeNode* getLastCommonNode(list<const TreeNode*> path1,
list<const TreeNode*> path2)
{
if (path1.empty() || path2.empty())
return nullptr;
auto iter1 = path1.cbegin();
auto iter2 = path2.cbegin();
const TreeNode* result = nullptr;
while (iter1 != path1.cend()
&& iter2 != path2.cend())
{
if (*iter1 == *iter2)
result = *iter1;
++iter1;
++iter2;
}
return result;
}
};
测试代码:
// ====================测试代码====================
void Test(const char* testName, const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2, TreeNode* pExpected)
{
if (testName != nullptr)
printf("%s begins: ", testName);
Solution s;
const TreeNode* pResult = s.getLastCommonParent(pRoot, pNode1, pNode2);
if ((pExpected == nullptr && pResult == nullptr) ||
(pExpected != nullptr && pResult != nullptr && pResult->val == pExpected->val))
printf("Passed.\n");
else
printf("Failed.\n");
}
// 形状普通的树
// 1
// / \
// 2 3
// / \
// 4 5
// / \ / \
// 6 7 8 9
void Test1()
{
TreeNode* pNode1 = CreateBinaryTreeNode(1);
TreeNode* pNode2 = CreateBinaryTreeNode(2);
TreeNode* pNode3 = CreateBinaryTreeNode(3);
TreeNode* pNode4 = CreateBinaryTreeNode(4);
TreeNode* pNode5 = CreateBinaryTreeNode(5);
TreeNode* pNode6 = CreateBinaryTreeNode(6);
TreeNode* pNode7 = CreateBinaryTreeNode(7);
TreeNode* pNode8 = CreateBinaryTreeNode(8);
TreeNode* pNode9 = CreateBinaryTreeNode(9);
TreeNode* pNode10 = CreateBinaryTreeNode(10);
ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode4, pNode6, pNode7);
ConnectTreeNodes(pNode5, pNode8, pNode9);
Test("Test1", pNode1, pNode6, pNode8, pNode2);
}
// 树退化成一个链表
// 1
// /
// 2
// /
// 3
// /
// 4
// /
// 5
void Test2()
{
TreeNode* pNode1 = CreateBinaryTreeNode(1);
TreeNode* pNode2 = CreateBinaryTreeNode(2);
TreeNode* pNode3 = CreateBinaryTreeNode(3);
TreeNode* pNode4 = CreateBinaryTreeNode(4);
TreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, pNode2, nullptr);
ConnectTreeNodes(pNode2, pNode3, nullptr);
ConnectTreeNodes(pNode3, pNode4, nullptr);
ConnectTreeNodes(pNode4, pNode5, nullptr);
Test("Test2", pNode1, pNode5, pNode4, pNode3);
}
// 树退化成一个链表,一个结点不在树中
// 1
// /
// 2
// /
// 3
// /
// 4
// /
// 5
void Test3()
{
TreeNode* pNode1 = CreateBinaryTreeNode(1);
TreeNode* pNode2 = CreateBinaryTreeNode(2);
TreeNode* pNode3 = CreateBinaryTreeNode(3);
TreeNode* pNode4 = CreateBinaryTreeNode(4);
TreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, pNode2, nullptr);
ConnectTreeNodes(pNode2, pNode3, nullptr);
ConnectTreeNodes(pNode3, pNode4, nullptr);
ConnectTreeNodes(pNode4, pNode5, nullptr);
TreeNode* pNode6 = CreateBinaryTreeNode(6);
Test("Test3", pNode1, pNode5, pNode6, nullptr);
}
// 输入nullptr
void Test4()
{
Test("Test4", nullptr, nullptr, nullptr, nullptr);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
return 0;
}