《剑指offer》面试题 68:树中两个结点的最低公共祖先(C++实现)

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-21 09:12   11   0

题目

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

代码

#pragma once

#include <vector>
#include <list>
using namespace std;

struct TreeNode
{
 int m_nValue;
 vector<TreeNode*> m_vChildren;
};

/* 普通树 通过利用辅助内存 用两个链表来存储根节点到给定节点的路径 
   转换成求两个链表的最后公共祖先 */

// 递归 遍历树获得对应节点的路径存入链表
bool getNodePath(TreeNode* pRoot, TreeNode* pNode, list<TreeNode*>& path)
{
 if (pRoot == pNode)
  return true;

 path.push_back(pRoot);
 bool found = false;
 vector<TreeNode*>::iterator iter = pRoot->m_vChildren.begin(); // 用到迭代器 横向查找树的子节点

 while (!found && iter < pRoot->m_vChildren.end())
 {
  found = getNodePath(*iter, pNode, path); // 递归 进入子树下一层
  ++iter;
 }

 if (!found)
  path.pop_back(); // 在最深层时没有找到则往回弹出链表

 return found;
}

// 由只读迭代器遍历找到两个链表的最后公共节点
TreeNode* getLastCommonNode(const list<TreeNode*>& path1, const list<TreeNode*>& path2)
{
 list<TreeNode*>::const_iterator iter1 = path1.begin();
 list<TreeNode*>::const_iterator iter2 = path2.begin();

 TreeNode* pLast = nullptr;
 while (iter1 != path1.end() && iter2 != path2.end())
 {
  if (*iter1 == *iter2)
   pLast = *iter1; // 开始相等的值会被后面相等的覆盖
  ++iter1;
  ++iter2;
 }

 return pLast;
}

TreeNode* getLastCommonParent(TreeNode* pRoot, TreeNode* pNode1, TreeNode* pNode2)
{
 if (pRoot == nullptr || pNode1 == nullptr || pNode2 == nullptr)
  return nullptr;

 list<TreeNode*> path1;
 list<TreeNode*> path2;
 getNodePath(pRoot, pNode1, path1);
 getNodePath(pRoot, pNode2, path2);
 
 return getLastCommonNode(path1, path2);
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP