当前位置: 首页 > news >正文

可视化图解算法35:在二叉树中找到两个节点的最近公共祖先(二叉树的最近公共祖先)

1. 题目

描述

给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足 1≤n≤105 , 节点值val满足区间 [0,n)

要求:时间复杂度 O(n)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。

节点本身可以视为自己的祖先

示例1

输入:

{3,5,1,6,2,0,8,#,#,7,4},5,1

返回值:

3

示例2

输入:

{3,5,1,6,2,0,8,#,#,7,4},2,7

返回值:

2

2. 解题思路

本题求解的是普通二叉树的公共祖先,即二叉树的节点值没有规律性(与二叉搜索树不同),因此只能分不同情况进行处理:

情况1:节点的值等于给定的值(满足给定的值p或q之一即可),该节点就是最近公共祖先

情况2:节点的值不等于给定的值,这时只能从左右子树中查找:

  1. 从节点的左子树中找;

  2. 从节点的右子树中找;

  3. 返回对应的节点:

    ①如果左右子树的结果都为null,返回null(说明左右子树中都没有公共祖先);

    ②左子树或右子树的结果有一个为null,返回不为null的结果(说明公共祖先存在于不为空的子树中);

    ③左右子树的结果都不为空,返回当前节点(说明当前节点为公共祖先)。

采用递归的方式查找公共祖先节点。

递推公式如下:

如果文字描述的不太清楚,你可以参考视频的详细讲解。

  • Python版本:数据结构笔试面试算法-Python语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Python语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1372246

  • Java版本:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1367354

  • Golang版本:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1364779

3. 编码实现

核心代码如下:

/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param root TreeNode类* @param o1 int整型* @param o2 int整型* @return int整型*/
func lowestCommonAncestor(root *TreeNode, o1 int, o2 int) int {// write code herereturn recursion(root, o1, o2).Val
}func recursion(root *TreeNode, v1 int, v2 int) *TreeNode {// 2. 递归终止条件:节点为空,直接返回if root == nil {return nil}// 1. 问题分解(递推公式)// 1.1 节点的值等于给定的值,该节点就是最近公共祖先if root.Val == v1 || root.Val == v2 {return root}// 1.2 节点的值不等于给定的值// 1.2.1 到左子树中找left := recursion(root.Left, v1, v2)// 1.2.2 到右子树中找right := recursion(root.Right, v1, v2)// 1.2.3 返回节点if left == nil && right == nil {//左右子树都没有找到,返回nilreturn nil} else if left == nil && right != nil {//左子树都没有找到,右子树找到,返回右子树return right} else if left != nil && right == nil {//右子树都没有找到,左子树找到,返回左子树return left} else {//左右子树都找到,返回当前节点return root}
}

具体完整代码你可以参考下面视频的详细讲解。

  • Python版本:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1372246

  • Java版本:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1367354

  • Golang版本:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1364779

4.小结

普通二叉树公共祖先的查找需要从左右子树中分别查找,再依据查找的结果进行判断:如果左右子树有一个子树查找到,则返回对应的子树;如果都查找到则返回当前的节点(当前节点就是公共祖先);如果都没有查找到,则返回Null。

《数据结构与算法》深度精讲课程正式上线啦!七大核心算法模块全解析:

  ✅   链表

  ✅   二叉树

  ✅   二分查找、排序

  ✅   堆、栈、队列

  ✅   回溯算法

  ✅   哈希算法

  ✅   动态规划

无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!

  • Python编码实现:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ss897667807

  • Java编码实现:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ss161443488

  • Golang编码实现:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ss63997

对于二叉树的相关算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:北方有佳人,绝世而独立。一顾倾人城,再顾倾人国。

相关文章:

  • 【LeetCode】删除排序数组中的重复项 II
  • 2025年渗透测试面试题总结-某步在线面试(题目+回答)
  • 开启智能Kubernetes管理新时代:kubectl-ai让操作更简单!
  • ZooKeeper工作机制与应用场景
  • 邻近标记技术:研究蛋白互作的利器(五)
  • base64与图片的转换和预览(高阶玩法)
  • 守护数字家园:个人博客安全防护指南
  • 云服务如何简化物联网设备生命周期(How Cloud Services Simplify IoT Device Lifecycles)?
  • 【Linux修炼手册】Linux开发工具的使用(一):yum与vim
  • 数据清洗(ETL/ELT)原理与工具选择指南:企业数字化转型的核心引擎
  • DevExpressWinForms-布局之SplitContainerControl
  • 基于CNN与SHAP可解释性分析的神经网络回归预测模型【MATLAB】
  • Python爬虫(21)Python爬虫进阶:Selenium自动化处理动态页面实战解析
  • 基于SpringBoot的校园周边美食探索及分享平台的设计与实现
  • C++函数传值与传引用对比分析
  • 笔试强训——第七周
  • 《面向对象》
  • C29-二维数组应用之找最大值及对应下标
  • 高能数造全固态电池干法电极高品质原纤化技术:驱动干法和全固态电池制造新进程
  • 【25软考网工】第五章(9)路由协议BGP、IS IS
  • 江西省直机关工委副书记熊亮华履新宜春市委常委、宣传部部长
  • 治沙“异瞳”男生疑似摆拍,团队称合作12天多期视频为策划拍摄
  • 习近平出席俄罗斯总统举行的欢迎仪式
  • 大四本科生已发14篇SCI论文?学校工作人员:已记录汇报
  • 秦洪看盘|受阻回落,蓄积新做多能量
  • 央行行长:未来还可以扩大结构性货币政策工具规模或创设新的政策工具