【LeetCode】剑指 Offer 68. 二叉树中两个节点的最低公共祖先 p326 -- Java Version

2023-05-16

1. 题目介绍(68. 二叉树中两个节点的最低公共祖先)

面试题68:二叉树中两个节点的最低公共祖先, 一共分为两小题:

  • 题目一:二叉搜索树的最近公共祖先
  • 题目二:二叉树的最近公共祖先

2. 题目1:二叉搜索树的最近公共祖先

题目链接:https://leetcode.cn/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/

2.1 题目介绍

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

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

在这里插入图片描述

【测试用例】:
在这里插入图片描述
【条件约束】:
在这里插入图片描述
【相关题目】:

  • 注意:本题与主站 235. 二叉搜索树的最近公共祖先 题目相同。

2.2 题解 – 迭代/递归 O(n) ⭐

时间复杂度O(n),空间复杂度O(n)
在这里插入图片描述

解题思路】:
由于二叉搜索树的性质,我们很容易就能找出两个节点的最低公共祖先。
……
二叉搜索树:位于左子树的节点的都小于父节点,位于右子树的节点都大于父节点;
因此,根据二叉搜索树的特性,我们只需要从树的根节点开始和两个输入的节点进行比较:

  • 如果当前节点的值比两个节点的值都,那么最低的共同父节点一定在当前节点的左子树上;
  • 如果当前节点的值比两个节点的值都,那么最低的共同父节点一定在当前节点的右子树上;
  • 如果一大一小,那么当前节点即为其最低的共同父节点。

……
实现策略】:
根据以上思路,实现方法可分为两种:

  1. 迭代法
  2. 递归法

迭代法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (root != null) {
            if (root.val > p.val && root.val > q.val) root = root.left;
            else if (root.val < p.val && root.val < q.val) root = root.right;
            else break;
        }
        return root;
    }
}

在这里插入图片描述
递归法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root.val < p.val && root.val < q.val)
            return lowestCommonAncestor(root.right, p, q);
        if(root.val > p.val && root.val > q.val)
            return lowestCommonAncestor(root.left, p, q);
        return root;
    }
}

在这里插入图片描述

3. 题目2:二叉树的最近公共祖先

题目链接:https://leetcode.cn/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/

3.1 题目介绍

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

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

在这里插入图片描述

【测试用例】:
>

【条件约束】:
>

【相关题目】:

  • 注意:本题与主站 236. 二叉树的最近公共祖先 题目相同.

3.2 题解 – 递归 O(n) ⭐

时间复杂度O(n),空间复杂度O(n)

解题思路】:
对于二叉树来说,与二叉搜索树不同之处就在于,没有了排序,无法直接根据值的大小来判断 p、q 存在的位置,那么我们要想找到二叉树中两个节点的最低公共祖先,就需要遍历一遍二叉树,对此我们可以进行分类讨论:
在这里插入图片描述
……
实现策略】:

  1. 首先判断当前节点是否为空,是否为 p 和 q 将其作为递归的结束条件;

  2. 分类讨论:

    • 当左右子树都找到时,返回当前节点;
    • 当只有左子树找到时,返回递归左子树的结果;
    • 当只有右子树找到时,返回递归右子树的结果;
    • 当左右子树都没找到时,返回空节点(此步可合并到2、3步省略)
  3. 大家是否存在这样一个疑惑,就是假设只有左子树找到,右子树没找到,那么返回左子树结果是否正确,验证后结果确实正确,这是因为,如果出现这种情况就说明输入的两个节点,其中有一个节点不是这个二叉树上的值,与题目中的说明不符,题目中说明的是两个节点都存在与二叉树中,不过出现这种情况返回的依旧是存在的那个输入节点,判定结果仍是对的。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    // 递归,分类讨论
    // 左右都有,返回当前节点
    // 左边有,返回左边
    // 右边有, 返回右边
    // 左右都没有,返回null
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);  // 左子树递归
        TreeNode right = lowestCommonAncestor(root.right,p,q);  // 右子树递归
        if (left != null && right != null) return root;
        return left != null ? left : right;     
    }
}

在这里插入图片描述

4. 参考资料

[1] 面试题68 - I. 二叉搜索树的最近公共祖先(迭代 / 递归,清晰图解)
[2] 剑指 Offer 68 - II. 二叉树的最近公共祖先(DFS ,清晰图解)
[3] 【视频】分类讨论乱如麻?一个视频讲透!(Python/Java/C++/Go)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【LeetCode】剑指 Offer 68. 二叉树中两个节点的最低公共祖先 p326 -- Java Version 的相关文章

  • 在 Spring Boot 中重新加载/刷新缓存

    我正在使用 Spring Boot 对于缓存 我使用 Ehcache 到目前为止一切正常 但现在我必须重新加载 刷新 那么我该如何执行此操作 以便我的应用程序不会出现任何停机时间 我在Spring Ehcache中尝试了很多方法 但它不起作
  • Eclipse 中的 Java 简单电子邮件程序

    我想制作一个简单的程序 您可以从其中发送电子邮件命令行 我找到了这个教程 http www tutorialspoint com java java sending email htm http www tutorialspoint com
  • TestNG 启动期间发生内部错误

    我创建了一个 TestNG 类 FirstTest java 当我将测试用例作为 TestNG Test 运行时 出现以下错误 期间发生内部错误 启动 FirstTest java lang NullPointerException Ecl
  • 如何在 Android 中恢复我的音频?

    我必须实现用于创建具有暂停和恢复状态的音频的应用程序 当我的应用程序作为启动时音频启动 当我按下模拟器上的后退按钮时 音频音乐处于暂停状态 但是当我的活动回来时从停止状态到前台我的音频音乐未恢复 这是我的代码 public class Au
  • 逐行读取 JTextPane

    有没有办法读取a的内容JTextPane逐行 很像 BufferedReader 吗 Element root textPane getDocument getDefaultRootElement 获得根元素后 您可以检查存在多少个子元素
  • 如何向 OkHttp 请求拦截器添加标头?

    我将这个拦截器添加到我的 OkHttp 客户端 public class RequestTokenInterceptor implements Interceptor Override public Response intercept C
  • Spring MVC 中的 CSRF(跨站请求伪造)保护

    我对春季的 CSRF 跨站请求伪造 保护有点困惑 不 我有我的 jsp 我的控制器和一个 Web 服务 我想要做的是在 Web 服务级别验证令牌 如果令牌匹配 则运行 Web 服务 在我的例子中执行数据库插入 JSP file
  • Eclipse 内容协助无法在枚举常量参数列表中工作

    使用 eclipse 当我输入以下内容时 public enum Foo A Integer private final Integer integer private Foo Integer integer this integer in
  • Java 中的 TreeSet 与 C#.net 的等效项

    我有 Java 代码 其中包含TreeSet 我想将代码转换为 C 我可以使用哪个等效集合 如果没有 请提出替代方案 那将是系统 集合 通用 SortedSet
  • JSF 错误 - IllegalStateException:PWC3999:提交响应后无法创建会话[重复]

    这个问题在这里已经有答案了 我是 JSF 新手 正在构建一个使用 Facelet 创建的应用程序 这是我的模板master xhtml
  • 在Tomcat中设置环境变量TESSDATA_PREFIX

    我们正在使用名为 Tess4J 的 Tesseract OCR Java 库 如果作为独立应用程序运行 它可以正常工作 它需要一个名为 TESSDATA PREFIX 的变量 其中包含 tessdata 配置和其他字符集相关文件 它也可以与
  • Android 防火墙与 VpnService

    我正在尝试使用 BS 项目的 VpnService 为 Android 实现一个简单的防火墙 我选择 VpnService 因为它将在非 root 设备上运行 它将记录连接并让您过滤连接 基于IP 有一个应用程序可以做到这一点 因此这是可能
  • Android Google 地图:隐藏整个地图的多边形或形状

    我试图隐藏除一个区域之外的整个地图 因为我使用的多边形在我想要显示的区域中有一个洞 问题在于 根据缩放的不同 空白区域会被多边形的颜色覆盖 或者多边形会失去其颜色 这是代码 polygon hide all world map float
  • Android 上的自定义视图和窗口属性

    我想要做的是在我的应用程序顶部添加一个视图 该视图类似于过滤器视图 我想操纵屏幕的颜色 并且我还希望能够同时更改屏幕的亮度时间 这两件事似乎是分开起作用的 但不能一起起作用 这是我的代码 添加视图 colourView new Layer
  • Java Swing JEditorPane:操作样式文档

    我的模型是与枚举类型关联的字符串队列 我试图在 JEditorPane 中显示该模型 队列中的每个元素作为一个单独的 HTML 段落 其属性基于关联的枚举类型 但是 我的更新方法并没有达到我想要的效果 我尝试将 HTML 字符串直接写入文档
  • Java Timer 类:如果其中一个任务抛出异常,则计时器任务停止执行

    new Timer scheduleAtFixedRate new TimerTask Override public void run System out println run throw new SomeRandomExceptio
  • 不想保留一对一的实体

    假设我有两节课Employee and Department In Employee我已经写了 OneToOne fetch FetchType EAGER cascade CascadeType ALL JoinColumn name d
  • 解析 SWIG 接口文件的结构属性

    这是我不久前问过的问题的延续 为通过参数返回的函数创建类型映射 https stackoverflow com questions 12793973 create a typemap for a function that returns
  • 为什么我的 Java 路径中添加了“L”?

    我在我的类路径中加载了一个 jar 在 iReport 中 如果重要的话 我确信它具有所需的方法 但是当我尝试测试连接 从而调用该 jar 时 我得到一个 java lang NoSuchMethodError 说它正在引用班上 Lorg
  • 丰富:数据表行跨度问题

    我需要创建一个 rich dataTable 甚至扩展 具有以下功能 我有一个公司类 其中包含产品对象的集合 我想展示下表 我仍然没有弄清楚如何使用子表执行此操作 在所有示例中 我发现子表具有与主表完全相同的列 据推测 我需要在前两列中使用

随机推荐