二叉树最近公共祖先(LCA)问题解析与实现
1. 项目概述二叉树最近公共祖先问题在二叉树相关算法中最近公共祖先Lowest Common Ancestor简称LCA是一个经典且高频出现的面试题。LeetCode第236题正是考察这个知识点题目要求给定一个二叉树和其中的两个节点找到这两个节点的最近公共祖先。这里的最近指的是在二叉树中深度最大的公共祖先节点。这个问题在实际开发中有诸多应用场景比如在版本控制系统中寻找两个分支的最近合并点在DOM树中查找两个元素的共同父节点或者在家族关系系统中计算两个人的最近共同祖先等。理解并掌握这个问题的解法不仅能帮助我们应对技术面试更能提升我们处理树形结构数据的思维能力。2. 核心概念解析2.1 二叉树基础回顾二叉树是每个节点最多有两个子节点的树结构通常称为左子节点和右子节点。在解决LCA问题时我们需要明确几个关键概念节点深度从根节点到该节点的路径长度祖先节点从根节点到该节点的路径上的所有节点都是其祖先公共祖先同时是两个节点祖先的节点最近公共祖先距离两个节点最近的公共祖先节点2.2 最近公共祖先的定义最近公共祖先是指在一个树结构中两个给定节点的所有公共祖先中距离这两个节点最近的那个节点。换句话说它是这两个节点在树中交汇的第一个点。举个例子考虑以下二叉树3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4节点5和1的LCA是3节点5和4的LCA是5节点7和8的LCA是33. 递归解法详解3.1 递归思路分析递归是解决树形结构问题的天然工具因为树本身就是递归定义的数据结构。对于LCA问题我们可以采用后序遍历左右根的方式自底向上地寻找公共祖先。核心思路是如果当前节点是p或q中的一个则返回当前节点分别在左右子树中递归查找p和q如果左右子树都返回非空节点说明当前节点就是LCA如果只有一边返回非空节点则返回该节点说明LCA在子树中3.2 递归实现代码class TreeNode: def __init__(self, x): self.val x self.left None self.right None class Solution: def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) - TreeNode: # 基准情况如果root为空或者root就是p或q直接返回root if not root or root p or root q: return root # 递归在左子树中查找 left self.lowestCommonAncestor(root.left, p, q) # 递归在右子树中查找 right self.lowestCommonAncestor(root.right, p, q) # 如果左右都找到了说明当前root就是LCA if left and right: return root # 如果只有一边找到返回找到的那边 return left if left else right3.3 递归过程图解让我们以之前的二叉树为例查找节点5和1的LCA从根节点3开始递归进入左子树5在节点5发现匹配p(5)返回5回到节点3递归进入右子树1在节点1发现匹配q(1)返回1在节点3左右子树都返回非空因此3是LCA4. 算法复杂度分析4.1 时间复杂度该算法需要访问二叉树中的每个节点一次因此时间复杂度为O(N)其中N是二叉树中的节点数量。这是最优的时间复杂度因为我们必须检查每个节点才能确定LCA。4.2 空间复杂度空间复杂度主要取决于递归调用的栈深度。在最坏情况下树退化为链表空间复杂度为O(N)。在平衡二叉树的情况下空间复杂度为O(logN)。5. 边界条件与特殊情况处理5.1 节点不存在的情况在实际应用中我们需要考虑p或q可能不在树中的情况。上述基础解法假设两个节点都在树中。如果需要处理节点不存在的情况可以修改算法class Solution: def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) - TreeNode: self.found_p False self.found_q False result self.findLCA(root, p, q) return result if (self.found_p and self.found_q) else None def findLCA(self, root, p, q): if not root: return None left self.findLCA(root.left, p, q) right self.findLCA(root.right, p, q) # 检查当前节点是否是p或q if root p: self.found_p True return root if root q: self.found_q True return root if left and right: return root return left if left else right5.2 其他边界情况当p就是q的祖先时应该返回p当q就是p的祖先时应该返回q当树为空时应该返回None当p或q为None时应该返回None6. 非递归解法对比6.1 使用父指针的迭代方法虽然递归解法简洁优雅但在某些情况下比如树非常深时我们可能需要考虑迭代解法。一种常见的方法是使用父指针从根节点开始遍历树记录每个节点的父指针从p开始向上访问所有祖先存入集合从q开始向上访问祖先第一个在集合中的就是LCAclass Solution: def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) - TreeNode: stack [root] parent {root: None} # 迭代直到找到p和q的父指针 while p not in parent or q not in parent: node stack.pop() if node.left: parent[node.left] node stack.append(node.left) if node.right: parent[node.right] node stack.append(node.right) # 收集p的所有祖先 ancestors set() while p: ancestors.add(p) p parent[p] # 查找q的祖先中第一个在p的祖先集合中的节点 while q not in ancestors: q parent[q] return q6.2 两种方法的比较方法时间复杂度空间复杂度适用场景递归O(N)O(H)代码简洁树深度不大时迭代父指针O(N)O(N)树很深可能栈溢出时7. 实际应用与变种问题7.1 实际应用场景版本控制系统Git中寻找两个分支的最近共同提交DOM操作查找两个HTML元素的最近共同父元素计算生物学在系统发育树中寻找物种的最近共同祖先社交网络计算两个人的最近共同好友或关系7.2 常见变种问题二叉搜索树的LCA利用BST性质可以更高效地解决多叉树的LCA原理类似但需要考虑多个子节点带父指针的树的LCA可以转化为链表相交问题多个节点的LCA扩展为寻找多个节点的最近公共祖先8. 常见错误与调试技巧8.1 新手常见错误混淆节点值比较和节点比较应该比较节点对象而非节点值错误if root.val p.val正确if root p忽略递归基准条件忘记处理root为None的情况错误理解最近返回了第一个找到的公共祖先而非最近的未考虑节点不在树中的情况当p或q不在树中时应返回None8.2 调试技巧可视化递归过程画出递归调用树标注每次递归的返回值打印调试信息在递归函数中添加打印语句显示当前节点和递归深度使用小型测试用例先从简单的3节点树开始测试边界测试测试p或q是根节点、p是q的祖先等情况9. 性能优化与进阶思考9.1 多次查询优化如果需要多次查询不同节点对的LCA可以考虑预处理技术欧拉序RMQ将LCA问题转化为RMQ问题Tarjan离线算法一次性处理所有查询二进制提升法预处理每个节点的2^k级祖先这些方法可以将单次查询时间优化到O(1)或O(logN)但需要额外的预处理时间和空间。9.2 非二叉树扩展对于一般的树结构不一定是二叉树LCA问题同样适用。常用的解法包括转化为RMQ问题通过DFS遍历记录欧拉序和深度序列使用并查集Tarjan离线算法的核心树链剖分将树分解为多条链加速查询10. 面试技巧与实战建议10.1 面试中的解题步骤明确问题确认输入输出询问边界条件节点是否一定存在树是否可能为空举例说明画一个小型例子手动计算LCA提出暴力解法先给出直观解法如记录路径然后比较优化思路分析暴力解法的问题引出递归/迭代优化代码实现编写清晰、模块化的代码测试验证用多个测试用例验证代码正确性10.2 常见面试问题如何证明你的算法是正确的如果树非常大递归解法会有什么问题如何修改算法处理节点可能不存在的情况在二叉搜索树中如何更高效地解决这个问题如果每个节点都有指向父节点的指针如何优化解法11. 相关题目推荐为了巩固对LCA问题的理解建议练习以下LeetCode题目235. 二叉搜索树的最近公共祖先利用BST性质优化1644. 二叉树的最近公共祖先 II处理节点可能不存在的情况1650. 二叉树的最近公共祖先 III节点有父指针的情况1676. 二叉树的最近公共祖先 IV查找多个节点的LCA1123. 最深叶节点的最近公共祖先LCA变种问题12. 个人经验分享在实际面试和刷题过程中我发现LCA问题有几个关键点需要特别注意递归终止条件一定要先处理root为None或root等于p/q的情况这个顺序不能错返回值理解递归函数返回的不是最终的LCA而是表示当前子树中是否包含p或q测试用例设计要包括p和q在不同侧、同侧、一个是另一个祖先等情况空间优化在面试中如果被问到可以讨论如何用迭代替代递归避免栈溢出一个容易忽略的细节是当p就是q的祖先时算法应该返回p而不是继续向上查找。这在递归解法中是自然处理的但在某些迭代实现中可能需要特殊处理。

相关新闻

数字化3.0时代:从大模型智能涌现到AI工程实践落地

数字化3.0时代:从大模型智能涌现到AI工程实践落地

1. 从“数字化3.0”到“智能涌现”:我们正站在怎样的路口? 最近和几个做企业服务和技术投资的朋友聊天,大家不约而同地提到一个词:“数字化3.0”。这个词听起来有点宏大叙事,但背后其实是我们每天都能感受到的、正在发…

2026/8/10 3:23:39 阅读更多 →
从被动镜像到主动智能体:面向网络物理人工智能的整体论数字孪生(HDT-Net)

从被动镜像到主动智能体:面向网络物理人工智能的整体论数字孪生(HDT-Net)

从被动镜像到主动智能体:面向网络物理人工智能的整体论数字孪生(HDT-Net) 论文原网页:https://arxiv.org/html/2608.06227v1 摘要 大模型、生成式AI在医疗、文娱领域已落地,但机器人、自动驾驶等物理AI系统部署时仍…

2026/8/10 3:23:39 阅读更多 →
3分钟免费获取通达信实时行情数据:Python量化交易终极指南

3分钟免费获取通达信实时行情数据:Python量化交易终极指南

3分钟免费获取通达信实时行情数据:Python量化交易终极指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 想要用Python进行量化交易却苦于金融数据接口昂贵且复杂?MOOTDX为…

2026/8/10 3:23:39 阅读更多 →

最新新闻

AI编程助手功能调整的思考:从Claude Code事件看开发者工具演进与应对

AI编程助手功能调整的思考:从Claude Code事件看开发者工具演进与应对

1. 事件回顾:一次突如其来的产品策略转向 今天早上,我的开发者社群和几个技术论坛直接炸了。消息源很简单,但冲击力巨大:Anthropic官方宣布,将Claude Code功能从其Claude Pro订阅计划中移除。这意味着,所有…

2026/8/10 4:20:11 阅读更多 →
Python零基础入门实战指南:20%核心语法与3个实用项目

Python零基础入门实战指南:20%核心语法与3个实用项目

如果你在B站、知乎、CSDN上搜索“Python零基础教程”,大概率会看到两类内容:一类是标题党,承诺“七天从入门到精通”,但内容零散不成体系;另一类是学院派教材,严谨但枯燥,新手学完第一章就想放弃…

2026/8/10 4:20:11 阅读更多 →
基于MATLAB霍夫变换的骨折X射线影像辅助检测系统构建

基于MATLAB霍夫变换的骨折X射线影像辅助检测系统构建

在实际医疗影像分析领域,X射线平片是骨折诊断最常用、最经济的手段。然而,面对海量的影像数据,尤其是在急诊或基层医疗场景下,医生可能存在视觉疲劳或经验不足导致的漏诊风险。因此,借助计算机视觉技术开发辅助检测系统…

2026/8/10 4:20:11 阅读更多 →
AI赋能Dragonwell Native性能分析:从黑盒监控到10倍优化机会自动发现

AI赋能Dragonwell Native性能分析:从黑盒监控到10倍优化机会自动发现

1. 从一次深夜告警说起:当性能瓶颈遇上“黑盒”凌晨两点,手机屏幕突然亮起,刺眼的告警信息让我瞬间清醒。线上一个核心的Java服务,其关键接口的P99响应时间曲线,在毫无征兆的情况下,像坐上了火箭一样垂直飙…

2026/8/10 4:20:11 阅读更多 →
【2027最新】基于SpringBoot+Vue的web人力资源管理系统管理系统源码+MyBatis+MySQL

【2027最新】基于SpringBoot+Vue的web人力资源管理系统管理系统源码+MyBatis+MySQL

博主介绍:💼 毕业设计解决方案 构建完整的毕业设计生态支撑体系,为学生提供从选题到交付的全链路技术服务: 技术选题库 微信小程序生态:精选100个符合市场趋势的前沿选题 Java企业级应用:汇集500个涵盖主流…

2026/8/10 4:20:11 阅读更多 →
GitHub将npm恶意软件公告同步至OpenSSF:开源供应链安全联防新范式

GitHub将npm恶意软件公告同步至OpenSSF:开源供应链安全联防新范式

如果你是一名开发者,最近在npm install时是否感觉比以往更安心了一些?或者,你是否曾好奇,那些被标记为“恶意”的 npm 包,其信息是如何被快速、准确地识别并传播到整个开发生态系统中的?这背后,…

2026/8/10 4:19:11 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →