图解LeetCode——剑指 Offer 68 - II. 二叉树的最近公共祖先

简介: 图解LeetCode——剑指 Offer 68 - II. 二叉树的最近公共祖先

一、题目

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

百科中最近公共祖先的定义为:

对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。

二、示例

2.1> 示例 1:

【输入】 root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

【输出】 3

【解释】 节点 5 和节点 1 的最近公共祖先是节点 3。

2.2> 示例 2:

【输入】 root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

【输出】 5

【解释】 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的
  • pq 为不同节点且均存在于给定的二叉树中。

三、解题思路

根据题目描述,会给我们两个节点,分别是TreeNode pTreeNode q,然后我们需要在一个二叉树中去寻找着两个给定节点的最近公共祖先。这个题与《剑指 Offer 68 - I. 二叉搜索树的最近公共祖先》很类似,只不过我们这个树是普通的二叉树,不能利用二叉搜索树的特性来解题了。

那么我们知道,针对某一个节点来说,它是具有左子树右子树这两个属性的,那么对于随机给出的p节点q节点来说,就会有如下3种情况,请见下图所示:

根据上图描述,我们可以得出如下3种情况:

情况1】当p节点q节点分别在根节点的左子树和右子树中时,那么根节点就是最近公共祖先节点。

情况2】当p节点q节点都在根节点的左子树中时,第一个遍历到的节点就是最近公共祖先节点。

情况3】当p节点q节点都在根节点的右子树中时,第一个遍历到的节点就是最近公共祖先节点。

所以,针对上面的分析,我们可以通过深度遍历来遍历二叉树中的节点,当发现某个节点等于p节点或者等于q节点,则终止这一侧子树的遍历。然后当根节点的左子树和右子树都遍历完毕后,再根据以上3种情况,返回这道题的最终结果即可。

解题思路我们说完了,下面还是按照惯例,以输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 8为例,看一下具体处理流程是怎么样子的。请见下图所示:

四、代码实现

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return null;
        TreeNode ln = lowestCommonAncestor(root.left, p, q);
        TreeNode rn = lowestCommonAncestor(root.right, p, q);
        return (ln != null && rn != null) ? root : (ln != null ? ln : rn);
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

相关文章
|
12天前
【LeetCode 44】235.二叉搜索树的最近公共祖先
【LeetCode 44】235.二叉搜索树的最近公共祖先
11 1
|
12天前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
10 0
|
12天前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
8 0
|
12天前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
9 0
|
12天前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
8 0
|
28天前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
2月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
50 6
|
2月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
99 2
|
28天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
47 7