二叉树:二叉树的最近公共祖先
二叉树的最近公共祖先
文章目录
- 一、题目描述
- 二、解题思路
- 三、代码解析
一、题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
以上面这个图为例子:
5和1 的最近公共祖先就是3。
二、解题思路
刚看到这个题,肯定会有点懵,我开始也很懵,根本不知道从何下手,没关系,只需要先将这个思路理解了,先将这个方法掌握啦,掌握的方法多了,慢慢就有了自己的思路了。
用什么遍历序列?
这题要问的是给定p,q的最近公共祖先。很明显,是找指定孩子结点的祖先结点。
那么,我们是不是应该先检查子孙,通过检查子孙返回的结果来判断当前结点是否是目标结点。比如上面的例子,最后返回的是3,这个3是我们在检查完5和1后,发现5和1满足条件才认定3是最终结果的。
那么请问大家,用哪个遍历顺序?
A:中左右
B:左中右
C:左右中答案明显是:C
根据遍历左右子树的结果来判断当前结点是不是要求的结点。
怎么用后序遍历解决这个问题?
首先考虑,我们对于每一个结点的左右子树应该返回什么内容,才能让判断这个结点是否是最近公共祖先?
还是刚才的例子,
我们发现3->left是5满足给定的p=5
我们发现3->right是1满足给定的q=1
所以,我们认为3是5,1的公共祖先。
那如果要求p = 6
, q = 1
的最近公共祖先呢?
明显能看出来,6和1的最近公共祖先还是3。
那是怎么判断的呢?递归遍历3的左子树,如果左子树出现目标p或者q,就p或者q一层层返回上来。
遍历5的时候,如果5的左子树或者右子树出现p或者q,就返回上来。
总之:
无论在这个树的哪个位置找到了p或者q都要能把p,q返回到上一层,方便上层结点做判断。
所以说,递归函数返回值,返回的就是这个子树中是否有p,或者q。
如果有p或者q,就返回p或者q,如果没有就返回NULL
。
怎么通过左右子树返回的值判断最终的结果呢?
左右子树返会值会出现那些情况,有那些值是我们要返回的?
首先,如果遇到p,q肯定要返回。
其次,如果找到了【最近公共祖先】肯定也要返回
再次,如果不是上面两种情况,返回NULL就行了。
三、代码解析
看了上面的解析,可能还有点懵,那下面再结合具体代码理解
template<class T>
TreeNode<T>* lowestCommonAncestor(TreeNode<T>* root, TreeNode<T>* p, TreeNode<T>* q) {//思路
/*题目给了两个二叉树结点的指针,要返回这两个指针的最近的公共祖先。首先,这个题只能使用后序遍历,左右中。因为后序是先访问两个叶子,再访问中间结点。那根据后序遍历的访问顺序怎么操作呢?我们将后序每个结点后序左右子树遍历的结果保存在left和right中。如果有p那left保存的就是p(只要左子树出现p就,整个左子树返回的就是p,q同理,右子树同理,如果p,q都没有出现,就返回NULL)这样,对每一个结点都可以得到这个结点左右子树返回来的值。我们就根据这个结点左右子树返回来的值来判断这个结点是不是p,q的最近公共结点。怎么判断呢?左右子树可能跟返回如下三个值:p, q, NULL那么请问,一个结点的左右子树满足那种情况的时候,这个结点是p, q的最近公共祖先呢?当然只有两种情况:left:q, right:p 和left:p, right:q这两种情况了。所以,这时候只需要做判断,如果左右子树返回的都不是NULL那么,当前处理的这个结点就是p,q的最近公共祖先了。结束。
*///1.返回值和参数:返回值仍然是Treenode//2.递归终止的条件/*什么时候递归终止?2.1 当前访问的结点是p或者q2.2 当前访问到了空节点NULL(这个树是空树,或者叶子结点的孩子)*/if (root == q || root == p || root == NULL) return root;//对叶子结点的处理//3.单层递归处理逻辑//3.1 后序遍历左子树TreeNode<T>* left = lowestCommonAncestor(root->left, p, q);//3.2 后序遍历右子树TreeNode<T>* right = lowestCommonAncestor(root->right, p, q);//3.3 后序遍历处理中间结点//问题:这里为什么判断的是左右子树返回值不为NULL,为什么不判断左右子树返回值是p,q?/*因为,我们要向上传递的是四种值:NULL,p,q,最近公共祖先如果,判断是左右子树返回的是否是p,q那么,如果左右子树有一个子树出现了【最近公共祖先】那这个结果会因为不是p,q而传递不上去。反之,我们之和NULL做比较,只要不是NULL的都往上传,那无论在哪里找到了【最近公共祖先】都会被递归返回上去。*///得到了这个结点左右子树的值,就要判断这个结点是不是p,q的最近公共结点了if (left != NULL && right != NULL) return root;//左右子树都不为空,说明左右子树返回的是p,q或者q,p具体顺序我们不关心if (left != NULL && right == NULL) return left;//一个不为空,返回不为空的那个else if (left == NULL && right != NULL) return right;//同理else {return NULL;//只剩下最后一种情况,左右两边都返回的是NULL}}
二叉树:二叉树的最近公共祖先相关推荐
- python代码实现二叉树中最低的公共祖先
python代码实现二叉树中最低的公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结 ...
- 十九、二叉树的最近的公共祖先
十九.二叉树的最近的公共祖先 文章目录 十九.二叉树的最近的公共祖先 题目描述 解题思路 上机代码: 题目描述 设顺序存储的二叉树中有编号为 i 和 j 的两个结点,请设计算法求出它们最近的公共祖先结 ...
- 7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分)
7-6 顺序存储的二叉树的最近的公共祖先问题 (10 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤100 ...
- 顺序存储的二叉树的最近的公共祖先问题
习题4.5 顺序存储的二叉树的最近的公共祖先问题 (25 分) 设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤1 ...
- 7-4 (小字辈) 7-5 (列出叶结点) 7-6 (顺序存储的二叉树的最近的公共祖先问题)
目录 7-4 小字辈 7-5 列出叶结点 7-6 顺序存储的二叉树的最近的公共祖先问题 总结: 7-4 小字辈 原题链接:题目详情 - 7-4 小字辈 (pintia.cn) 思路: 利用一维数组下标 ...
- 二叉树:最近的公共祖先 Lowest Common Ancestor of a Binary Tree
已知二叉树,求二叉树中给定的两个节点的最近公共祖先. 最近公共祖先: 两节点v与w的最近公共祖先u,满足在树上最低(离根最 远),且v,w两个节点都是u的子孙. 如上二叉树,6和8号节点的公共祖先有4 ...
- 7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)
设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值. 输入格式: 输入第1行给出正整数n(≤),即顺序存储的最大容量:第2行给出n个非负整数,其间以空格分隔. ...
- 二叉树中的最近公共祖先
对于二叉树中任意两个结点p和q,可能存在如下的情形: p是q的祖先,此时p是p和q的最近公共祖先 q是p的祖先,此时q是p和q的最近公共祖先 p和q没有父子关系. 如果设p和q的最近公共祖先为x.如果 ...
- 【学透二叉树-二叉搜索树(二叉树)的最近公共祖先】
示例: 代码实现: class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q ...
- LeetCode实战:二叉树的最近公共祖先
背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a bin ...
最新文章
- npm install 报错 汇总_R包安装报错的日常
- java gps 距离计算_java计算两个GPS经纬度之间的距离(转)
- Redis源码剖析(八)链表
- 单页面 Web 应用(Single Page Application,SPA)的工作原理介绍
- 刚安装Vs2008,安装时它弹出了一个一些常见问题的解决方案页,记录下
- php 空模块,tp5.1配置空模块,空方法
- 操作mysql_操作mysql
- 高考数据分析和读书感悟
- centos7.5配置ntp时间服务器
- mac系统下安装pycharm
- 股票模拟交易php,股票模拟图,股票交易记录生成器
- TSC2004 电阻式触摸屏控制器驱动问题
- ❤️ 硬核玩游戏:200行代码给你整个俄罗斯方块 ❤️
- themeforest 免费模板
- 从汽车到可穿戴设备的设计都利用 PMIC 实现电源效率
- HarmonyOS的万里长征和万里长城
- 傲气雄鹰android 3dm,傲气雄鹰 重载
- po/mo互相转换工具
- 多线程高速下载百度云
- Wannafly挑战赛26
热门文章
- 实不相瞒,我做海外TikTok搬运视频一年的收入,可能是你10年的工资
- CentOS下Qt安装
- 大白菜 装系统 win7
- 饥荒开服(含各种踩雷)
- 猫咖小程序开发有何优势?具备什么功能版块?
- 20190919CF训练
- Ubuntu拼音输入不正常解决
- 16.集合框架(ArrayList,Vector,LinkedList,泛型(Generic),可变参数,增强for循环)
- openGauss亮相VLDB2020,展示内存优化研究成果
- 黑苹果——推荐台式机(翻译自tonymacX86)