【剑指】68.树中两个结点的最低公共祖先

题目描述

输入两个二叉树结点,求它们的最低公共祖先。

算法分析

用两个链表分别保存从根节点到输入的两个节点的路径,然后把问题转换成两个链表的最后公共节点。

提交代码:

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;
}

猜你喜欢

转载自blog.csdn.net/ansizhong9191/article/details/81506693