Find LCA in Binary Tree in Java2025年5月10日 | 阅读 8 分钟 最低公共祖先 (LCA) 是二叉树中两个节点的祖先,它是树中最深的包含这两个指定节点作为后代的节点。它在分层设置、网络路由和树形计算等多种应用中发挥着重要作用。 示例 1
示例 2
示例 3
使用数组存储节点从根到节点的路径的方法我们分别查找并存储从根到两个节点的路径到两个单独的列表中。通过比较这些路径,我们识别出最后一个公共节点,即 最低公共祖先 (LCA)。此方法通过跟踪确切的遍历序列,确保系统地确定 LCA。 算法步骤 1: 实现递归,将从根到每个目标节点的路径保存在列表中。如果找到目标节点,则停止进一步的递归。 步骤 2: 如果一个节点未达到目标,则将其从路径中删除,并继续在另一个子树中搜索。这保证了只记录正确的路径。 步骤 3: 同时遍历两条存储的路径,找到它们不同的点。在此点之前的节点是公共祖先。 步骤 4: 在发散之前,两条路径中的最后一个公共节点是最低公共祖先 (LCA)。它是两个目标节点共享的最深节点。 步骤 5: 打印 LCA 节点的值作为结果,因为它代表给定节点的最低共享祖先。 让我们在 Java 程序中实现上述算法。 输出 LCA of 4 and 5 is: 2 时间复杂度: O(N) – 遍历树和比较路径都为 O(N)。 空间复杂度: O(N) – 递归栈和路径存储需要 O(N) 空间。 使用单次遍历的方法与存储路径不同,可以使用 递归 在一次遍历中找到最低公共祖先 (LCA)。此方法通过验证节点是否位于给定节点的路径上来有效地识别 LCA。 算法步骤 1: 如果根节点为 null 或等于 n1 或 n2,则将其作为可能的 LCA 返回。 步骤 2: 在左子树中对 n1 和 n2 进行递归搜索,并保存结果。 步骤 3: 在右子树中对 n1 和 n2 进行递归搜索,并保存结果。 步骤 4: 如果左右子树的结果均不为 null,则当前节点是 LCA,因为 n1 和 n2 位于不同的子树中。 步骤 5: 如果只有一个子树产生非 null 结果,则将其作为 LCA 返回;否则,如果两个子树都不包含 n1 或 n2,则返回 null。 让我们在 Java 程序中实现上述算法。 输出 LCA of 4 and 5 is: 2 时间复杂度: O(N),其中 N 是节点数(因为每个节点都被访问一次)。 空间复杂度: O(H),其中 H 是树的高度(由于递归调用)。 二叉树中的递归 LCA 方法二叉树中的递归 LCA 方法利用 深度优先搜索 (DFS) 来识别最低公共祖先。它检查节点是否与给定值之一匹配。如果左右子树都包含一个节点,则当前根成为 LCA。否则,返回非 null 子树的结果作为 LCA。顶部表单 底部表单 算法步骤 1: 如果根节点为 null,则返回 null。如果它与任一给定节点匹配,则立即返回根节点。 步骤 2: 递归地在左子树和右子树中搜索节点。 步骤 3: 如果两个子树的结果均不为 null,则当前根是最低公共祖先 (LCA)。 步骤 4: 如果只有一个子树返回非 null 值,则将该节点作为 LCA 返回。 步骤 5: 在找到 LCA 之前,检查树中是否存在这两个节点。如果其中任何一个丢失,则返回 null,因为 LCA 不存在。 让我们在 Java 程序中实现上述算法。 输出 LCA of 4 and 5 is: 2 时间复杂度: O(N),因为该算法最多遍历每个节点一次。 辅助空间复杂度: O(H),其中 H 是树的高度(对于倾斜树为 O(N),对于平衡树为 O(log N))。 下一个主题Java Top 10 库 |
异常处理是Java编程的一个关键方面,它允许开发人员优雅地处理意外错误并保持应用程序的稳定性。Java开发人员遇到的一个常见异常是InvocationTargetException。在本节中,我们将探讨InvocationTargetException是什么,它的原因以及如何...
5 分钟阅读
Java 是一种多功能编程语言,以其丰富的类和方法库而闻名,这些库使开发人员能够创建复杂且交互式的图形用户界面 (GUI)。在 Java 中创建 GUI 组件时,setBounds() 方法起着至关重要的作用。在本节中,...
阅读 4 分钟
这是 Google、Amazon、TCS、Accenture 等顶级 IT 公司面试中经常出现的问题。通过解决该问题,人们希望检查面试者的逻辑能力、批判性思维和解决问题的能力。因此,在本节中,我们将……
阅读 13 分钟
?序列化是 Java 中的一种强大机制,它允许将对象转换为字节流,然后可以存储或传输该字节流,之后再将其重构回原始对象。它为持久化对象状态或在不同应用程序之间传输对象提供了一种简单的方法……
阅读 4 分钟
Java 中的主线程是任何 Java 程序的关键组件。当 Java 程序启动时,线程会自动创建,并维护应用程序的 main() 方法。main() 方法作为程序的入口点,是初始方法...
阅读9分钟
在本节中,我们将学习如何使用 while 循环、for 循环和递归在 Java 中反转数字。要反转数字,请按照以下步骤操作:首先,我们使用模(%)运算符找到给定数字的余数。将变量 reverse 乘以...
阅读 4 分钟
问题陈述 复制整数堆栈的示例最好描述如下:通常,我们需要一个辅助堆栈或其他数据结构来建立这种情况。当然,在这种情况下,我们没有额外的空间进行克隆,所以我们需要...
5 分钟阅读
? 构造函数是在创建类的实例变量时用于初始化实例变量的代码块。类中的默认构造函数在对象创建时被调用。但是,我们也可以使用带参数的构造函数来初始化数据成员,...
阅读 2 分钟
在本节中,我们将通过适当的示例讨论什么是 zigzag 数组(锯齿形数组)。我们还将创建一个 Java 程序来将普通数组转换为 zigzag 数组,反之亦然。什么是 zigzag 数组?一个数组称为……
阅读 6 分钟
类似于 YACC,它也是一个解析器。是 Java Compiler-Compiler 的简写。它是一个由 Oracle Corporation 开发的开源流行解析器生成器和词法分析器生成器工具。它用 Java 编程语言编写。它在 BSD 许可证下许可....
阅读 6 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India