【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现

【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现
在这里插入图片描述
🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:Java.数据结构
在这里插入图片描述


在这里插入图片描述


【前言】

二叉树的最近公共祖先是数据结构中的经典问题,无论是算法面试还是实际开发都高频出现。本文将从问题本身出发,拆解递归法与栈存路径法两种核心思路的逻辑步骤,并附上完整代码实现,帮你快速掌握这一考点。

文章目录:

一、二叉树的最近共同祖先

在这里插入图片描述

二、思路分析

方法一:递归法

判空

  • 如果根节点为空,直接返回null
  • 如果当前节点是p或者q,那么这个节点就是最近公共祖先

递归

  • 分别遍历当前节点的左子树和右子树,找到p和q的最近公共祖先,存于TreeNode leftRet或者TreeNode rightRet

结果

  • 如果左右子树都找到,那么当前节点就是p和q的最近公共祖先
  • 如果左子树找到,那就返回左子树的结果;

如果右子树找到,那就返回右子树的结果;

在这里插入图片描述

方法二:栈存路径法

获取路径

通过深度优先搜索,分别找到从根节点到p和q的路径中所有节点,并分别存入两个栈中

对齐栈长度

比较两个栈中元素长度,将较长的栈中元素弹出,然后比较两个栈中的下一深度元素是否相等

找公共祖先

同时弹出两个栈中不相等的栈顶元素,第一个相同的节点就是最近公共祖先

在这里插入图片描述

三、代码展示

方法一:递归法

publicTreeNodelowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q){//当前节点为空,直接返回nullif(root ==null){returnnull;}//当前节点是p或者q,返回当前节点(祖先)if(root == p || root == q){return root;}//递归探索左子树,找到p和q的最近祖先TreeNode leftRet =lowestCommonAncestor(root.left, p, q);//递归探索右子树,找到p和q的最近祖先TreeNode rightRet =lowestCommonAncestor(root.right, p, q);//左子树和右子树都找到if(leftRet !=null&& rightRet !=null){return root;//左子树找到}elseif(leftRet !=null){return leftRet;}else{//右子树找到return rightRet;}}

方法二:栈存路径法

publicbooleangetPath(TreeNode root,TreeNode node,Stack<TreeNode> stack){if(root ==null){returnfalse;}//将当前节点压入路径 stack.push(root);//找到目标节点if(root == node){returntrue;}//递归搜索左子树boolean flg =getPath(root.left,node,stack);if(flg){returntrue;}//递归搜索右子树 flg =getPath(root.right,node,stack);if(flg){returntrue;}//左右子树都没找到,弹出当前节点 stack.pop();returnfalse;}publicTreeNodelowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q){if(root ==null){returnnull;}//找到跟到p和q的路径Stack<TreeNode> stackp =newStack<>();Stack<TreeNode> stackq =newStack<>();getPath(root,p,stackp);getPath(root,q,stackq);//对齐两个栈长度int sizep = stackp.size();int sizeq = stackq.size();int size = sizep-sizeq;if(size>0){//stacp更长,弹出多余元素while(size !=0){ stackp.pop(); size--;}}else{////stacq更长,弹出多余元素 size = sizeq-sizep;while(size !=0){ stackq.pop(); size--;}}//此时两个栈大小一样,//同时弹出栈顶,找到相同的while(!stackp.isEmpty()&&!stackq.isEmpty()){if(stackp.peek().equals(stackq.peek())){return stackp.peek();} stackp.pop(); stackq.pop();}returnnull;}

四、总结

通过递归法的“自底向上”回溯,以及栈存路径法的“路径对比”思路,我们可以高效求解二叉树的最近公共祖先问题——前者利用递归特性简化代码,后者通过显式路径存储更直观易懂。结合本文的思路分析与代码示例,你可以根据场景灵活选择解法,轻松应对这类二叉树算法题。

Read more

openclaw多Agent和多飞书机器人配置

增加Agent多个飞书机器人 一个Agent尽量只用一个飞书机器人配置 一:先增加新的agent # 创建新的Agent,命名为new-agnet openclaw agents add new-agnet # 查看创建结果 openclaw agents list 二:新的agent与新的飞书链接 配置agnet下的channels: 在命令行输入 # 配置new-agnet机器人(替换为实际App ID和App Secret) openclaw config set agents.new-agnet.channels.feishu.appId "你的new-agnet 飞书 App ID" openclaw config set agents.new-agnet.channels.feishu.appSecret "你的new-agnet 飞书 App Secret"

By Ne0inhk
医疗连续体机器人模块化控制界面设计与Python库应用研究(下)

医疗连续体机器人模块化控制界面设计与Python库应用研究(下)

软件环境部署 系统软件架构以实时性与兼容性为核心设计目标,具体配置如下表所示: 类别配置详情操作系统Ubuntu 20.04 LTS,集成RT_PREEMPT实时内核补丁(调度延迟<1 ms)开发环境Python 3.8核心库组件PyQt5 5.15.4(图形界面)、OpenCV 4.5.5(图像处理)、NumPy 1.21.6(数值计算) 该环境支持模块化控制界面开发与传感器数据的实时融合处理,为连续体机器人的逆运动学求解(如FB CCD算法测试)提供稳定运行基础[16]。 手眼协调校准 为实现视觉引导的精确控制,需完成相机与机器人基坐标系的空间映射校准,具体流程如下: 1. 标识点布置:在机器人末端及各段首尾、中间位置共固定7个反光标识点,构建臂型跟踪特征集[29]; 2. 数据采集:采用NOKOV度量光学动作捕捉系统(8台相机,

By Ne0inhk

ESP32 小智 AI 机器人入门教程从原理到实现(自己云端部署)

此博客为一篇针对初学者的详细教程,涵盖小智 AI 机器人的原理、硬件准备、软件环境搭建、代码实现、云端部署以及优化扩展。文章结合了现有的网络资源,取长补短,确保内容易于理解和操作。 简介: 本教程将指导初学者使用 ESP32 微控制器开发一个简单的语音对话机器人“小智”。我们将介绍所需的基础原理、硬件准备、软件环境搭建,以及如何编写代码实现语音唤醒和与云端大模型的对接。通过本教程,即使没有深厚的 AI 或嵌入式经验,也可以一步步制作出一个能听懂唤醒词并与人对话的简易 AI 机器人。本教程提供详细的操作步骤、代码示例和图示,帮助您轻松上手。 1. 基础原理 ESP32 架构及其在 AI 领域的应用: ESP32 是一款集成 Wi-Fi 和蓝牙的双核微控制器,具有较高的主频和丰富的外设接口,适合物联网和嵌入式 AI 应用。特别是新版的 ESP32-S3 芯片,不仅运行频率高达 240MHz,还内置了向量加速指令(

By Ne0inhk
数据库基础与MySQL核心组件解析

数据库基础与MySQL核心组件解析

—数据库专栏— 数据库基础与MySQL核心组件深度解析 * @[toc](数据库基础与MySQL核心组件深度解析) * 一、数据库基础:为什么我们需要它? * 1.1 什么是数据库? * 1.2 使用数据库的九大作用 * 二、关系型数据库与主流产品 * 2.1 关系型数据库(Relational Database)定义 * 2.1 非关系型数据库 * 2.2 主流关系型与非关系型数据库 * 三、MySQL安装与核心配置 * 3.1 MySQL 服务端程序 `mysqld` * 3.2 数据库服务器、数据库与表的关系 * 3.3 选项(配置)文件详解 * 四、MySQL客户端工具 * 五、客户端与服务器的通讯方式 * 5.1 C/

By Ne0inhk