一、二叉搜索树中两节点的最小公共祖先:

最初级的题目,在一颗二叉搜索树中寻找两节点的最小公共祖先。根据二叉搜索树的特征,从根节点开始查找,若两节点的val值都小于当前节点,则他们的最小公共祖先就去左子树找,若两节点的val值都大于当前节点,则他们的最小公共祖先就去右子树找。直到一个节点的值小于当前节点,另一个节点的值大于当前节点,那么当前节点为最小公共祖先,即为找到了可以返回了。

c++代码:

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
{if(root == NULL)return root;if (p->val<root->val && q->val<root->val)return lowestCommonAncestor(root->left, p, q);else if(p->val>root->val && q->val>root->val)return lowestCommonAncestor(root->right, p, q);return root;
}

二、二叉树中两节点的最小公共祖先:

1、二叉树有指向父节点的指针:当二叉树中有指向父节点的指针时,可以倒过来看待这个问题,即为求两个链表的公共节点。从当前节点开始往根节点数,记录总共有多少个节点,记下数字。然后大数字的链表上先走几步到数字一样,再两节点都一起往根节点走,第一个相同的节点即为最小公共子节点。参见求链表相交的部分

2、二叉树没有指向父节点的指针:

这是普通的二叉树中求两节点的最小公共祖先。

思路一:二叉树中两节点无外乎这样几种情况,两节点p和q相等;p是q的子树或子树中的节点;q是p的子树或子树中的节点;q和p是两支子树,这时候可以递归找到他们的父节点继续前面的思路;

C++代码如下:

 bool ischild(TreeNode *pa, TreeNode *ch){if (ch == pa || pa==nullptr)return false;if (pa->left==ch || pa->right==ch)return true;return ischild(pa->left, ch)||ischild(pa->right, ch);}TreeNode* find_pa(TreeNode* root, TreeNode*cur){if (root->left == cur || root->right==cur)return root;if (ischild(root->left, cur))return find_pa(root->left, cur);elsereturn find_pa(root->right, cur);}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (p==q)return q;if (ischild(p, q))return p;if (ischild(q,p))return q;TreeNode *p_pa=find_pa(root, p);TreeNode *q_pa=find_pa(root, q);if (ischild(p_pa, q_pa) || p_pa==q_pa)return p_pa;else if(ischild(q_pa, p_pa))return q_pa;elsereturn lowestCommonAncestor(root, p_pa, q_pa);}

思路二:简单直接一点。当root非空时,不断从其左右子数搜索,①如果两节点都在其左子树,对其左子树节点递归搜索;②如果两节点都在其右子树,对其右子树节点递归搜索;③如果一个节点在左子树一个节点在右子树,则当前节点即为最小公共祖先。

C++代码如下:

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root==NULL || root == p|| root==q)return root;if(p == q)return p;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right,p,q);if (left!=NULL && right!=NULL)return root;else if(left == NULL)return right;return left;}

三、普通树中两节点的最小公共祖先:

1、树有指向父节点的指针:这种情况等同求链表的公共节点。同上参见求链表相交的部分

2、树没有指向父节点的指针:此种情况我觉得可以参见上述第二种普通二叉树求最小公共祖先(LCA)的方法,只是每次要在当前节点的每一个子树搜索。然而现在记录另外一种方法,参加剑指offer50题:可以用两个辅助空间,在当前数中搜索两个节点的路经并存下来。然后从根节点开始依次往后比较,记录下最后一个相等的节点即为最小公共祖先。

C++代码:

寻找路经:

 bool GetNodePath(TreeNode *pRoot, TreeNode *pNode, list<TreeNode*>&path){if (pRoot==pNode)return true;path.push_back(pRoot);bool found=false;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*>::const_iterator iterator1=path1.begin();list<TreeNode*>::const_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 || pRoot==pNode1 || pRoot==pNode2) return pRoot;if (pNode1 == pNode2)  return pNode1;List<TreeNode*>path1, path2;GetNodePath(pRoot,pNode1,path1);GetNodePath(pRoot,pNode2,path2);return GetLastCommonNode(path1,path2);}

转载于:https://www.cnblogs.com/weiyi-mgh/p/6612146.html

两节点的最小公共祖先LCA相关推荐

  1. 数据结构-寻找二叉树两节点的最近公共祖先(Java)

    寻找最近公共祖先 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p.q,最近公共祖先表示为一个节点 x,满足 ...

  2. 二叉链表之寻找两节点的最近公共祖先☆

    题目:p.q分别为指向该二叉树中任意两个节点的指针,试编写算法ancestor(root,p,q,r),找到p.q的最近公共祖先节点r 分析:         上一道题其实可以给我们一些启示,就是我们 ...

  3. 由浅入深:求给定两个树节点的最低公共祖先(二叉树、普通树结构)JAVA实现

    最近看了一道面试题目,觉得很有意思,而且常常被问到,今天综合归纳了一下这道题目,并给出了各种变形题目,附上JAVA版的程序解答. 题目是这样的:寻找二叉树的最低公共祖先?(其中隐含着一个盲点:树是什么 ...

  4. LeetCode 2096. 从二叉树一个节点到另一个节点每一步的方向(最小公共祖先)

    文章目录 1. 题目 2. 解题 1. 题目 给你一棵 二叉树 的根节点 root ,这棵二叉树总共有 n 个节点. 每个节点的值为 1 到 n 中的一个整数,且互不相同. 给你一个整数 startV ...

  5. 牛客题霸 [ 在二叉树中找到两个节点的最近公共祖先] C++题解/答案

    牛客题霸 [ 在二叉树中找到两个节点的最近公共祖先] C++题解/答案 题目描述 给定一棵二叉树以及这棵树上的两个节点 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点. 题解: 我们想想最 ...

  6. 在二叉树中找到两个节点的最近公共祖先(C++)

    在二叉树中找到两个节点的最近公共祖先 描述   给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点. 数据范围:树上节点数满足1 ...

  7. 2022-05-22:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p

    2022-05-22:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p.q,最近公共祖先表示为一个节点 x,满足 x ...

  8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 三种情况: 1).如果左边为空,右边不为空,则右边的第一个节点就为公共祖先 2).如果右边为空,左边不为空,则左边的第一个节点就为公共祖先 3) ...

  9. Java 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

    代码中的二叉树长这个样子↓↓↓ 找到该树中两个指定节点的最近公共祖先,有三种情况,如图: import java.util.*; import java.util.Queue; //下面的所有求结点总 ...

最新文章

  1. python -m json.tool 中文乱码 Format JSON with python
  2. struts2下的helloworld(如何让第一个struts2跑起来)——struts2第一讲
  3. MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
  4. iptables做路由转发服务器经典案例
  5. Eclipse没有server 配置Tomcat
  6. Centos7 安装Go环境
  7. 进度条小飞机移动动画
  8. cocos-2d iphone入门(二) cocos2d源代码生成查询文档
  9. 阿里13篇论文入选数据库顶会!PolarDB技术被认为引领数据库发展方向
  10. 绿盟科技 linux漏洞,apache漏洞修复(绿盟科技漏洞)
  11. 手机音乐计算机软件,盘点适合手机音频剪辑软件
  12. 利用ArcGIS做土地利用转移矩阵
  13. fastDFS原理及环境搭建
  14. 对numpy的数组取补集运算
  15. html上绑定回车事件,js/jquery中input 绑定回车enter事件的代码
  16. 学习和使用Oracle的基本Sql语句
  17. linear regreesion 线性回归
  18. 中易云 易云系统 电镀废水处理远程监控解决方案
  19. STM32F103C8T6定时器
  20. 遇到“该网页无法正常运作”,利用php的log查找错误

热门文章

  1. element走马灯自动_Element Carousel 走马灯的具体实现
  2. leetcode最小面积_LeetCode—— 939. 最小面积矩形(JavaScript)
  3. java udp 工具类_java基于UDP实现图片群发功能
  4. oracle 多个实例互相切换实例
  5. mysql 删除数据 降低_活见鬼,明明删除了数据,空间却没减少!
  6. java com dll_通过COM组件方式实现java调用C#写的DLL文件
  7. LISP标注路线桩号_CAD插件标桩号的AutoLISP程序语言求解释并译成中文,谢谢
  8. php网站后台密码加密,thinkphp 后台登陆密码加密传入密钥
  9. delphi 怎么监测image有没有变动_社会舆情监测引导应对解决方案
  10. 批量处理文件,除了 Python,不妨试试 VIM!