12.30 二叉树中等题

236. 二叉树的最近公共祖先

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

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

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

思路1:

要让depth尽可能大,则如果从底向上去遍历节点,那第一个满足是p、q公共祖先的节点即是答案

细节:后序遍历是从底向上遍历二叉树

采用递归方法进行后序遍历:

1.递归结构:

        TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

终止递归的条件:root==nullptr

判断是否为P、Q的祖先节点:判断left和right是否为null并重新写一个isChild进行递归判断,

class Solution {
public:bool isChild(TreeNode* root,TreeNode* target){if(root==target) return true;else if(root==NULL) return false;return isChild(root->left,target) || isChild(root->right,target);}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点if(left!=NULL) return left;else if(right!=NULL) return right;else if(isChild(root,p)&&isChild(root,q)) return root;return NULL;}
};

这段代码的时间复杂度是O(N^2),其中N是二叉树中节点的数量。原因是在lowestCommonAncestor函数中,对于每个节点都会调用isChild函数,而isChild函数的时间复杂度是O(N),因为它需要递归遍历整个树来查找目标节点。

下面这个方法的复杂度为o(N)。

思路2:

代码随想录 (programmercarl.com)

要让depth尽可能大,则如果从底向上去遍历节点,那第一个满足是p、q公共祖先的节点即是答案

细节:后序遍历是从底向上遍历二叉树

采用递归方法进行后序遍历:

递归结构:

        TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

终止递归的条件:root==nullptr或==p或==q

        if (root == q || root == p || root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

判断该节点是否为P、q公共祖先节点可以利用返回的left、right值:

left、right的取值有四种情况:

1.left right 都为nullptr

则该root不是p q的祖先节点

2.left 为nullptr而right不为nullptr

则left不会是 p q的祖先节点,right可能是

3.right 为nullptr而left不为nullptr

则right不会是 p q的祖先节点,left可能是

4.left right 都不为nullptr

则root一定为 p 、q的公共祖先节点。该root返回到上一层递归中时,与该root对应的兄弟节点一定会是nullptr,则继续返回该root,直到第一层。

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == q || root == p || root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点if (left != NULL && right != NULL) return root;if (left == NULL) return right;return left;}
};

在最坏情况下,需要遍历整个二叉树,因此时间复杂度是O(N),其中N是二叉树中节点的数量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/823401.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

yolov8实战第四天——yolov8图像分类 ResNet50图像分类(保姆式教程)

yolov8实战第一天——yolov8部署并训练自己的数据集(保姆式教程)_yolov8训练自己的数据集-CSDN博客在前几天,我们使用yolov8进行了部署,并在目标检测方向上进行自己数据集的训练与测试,今天我们训练下yolov8的图像分类…

【滑动窗口】C++算法:K 个不同整数的子数组

作者推荐 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 本题涉及知识点 滑动窗口 LeetCoe992 K 个不同整数的子数组 给定一个正整数数组 nums和一个整数 k,返回 nums 中 「好子数组」 的数目。 如果 nums 的某个子数组中不同整数的个数恰好为 …

【AI导师】利用Coding Agent完成AIGC编程

利用Coding Agent完成AIGC编程 一、前言二、Coding Agent三、1024code四、AI导师README项目初版功能定义代码结构设计方案函数方法设计方案迭代记录 一、前言 AI产品的发展确实在过去两年年中取得了显著进展,尤其是在编程领域。一开始,ChatGPT和类似的语…

前后端分离架构的特点以及优缺点

文章目录 一、前后端不分离架构(传统单体结构)1.1 什么是前后端不分离1.2 工作原理1.3 前后端不分离的优缺点1.4 应用场景 二、前后端分离架构2.1 为什么要前后端分离2.2 什么是前后端分离2.3 工作原理2.4 前后端分离的优缺点 参考资料 一、前后端不分离架构(传统单体结构) 首…

阿里后端实习二面

阿里后端实习二面 记录面试题目,希望可以帮助到大家 类加载的流程? 类加载分为三个部分:加载、连接、初始化 加载 类的加载主要的职责为将.class文件的二进制字节流读入内存(JDK1.7及之前为JVM内存,JDK1.8及之后为本地内存)&…

EBU7140 Security and Authentication(一)常见加密算法

前言 主要根据 EBU7140 课程内容整理,比较偏向应试~ Block1:介绍课程,传统加密方式。 Block2:公钥加密的原理和应用。 Block3:一些特定安全协议技术(如防火墙 Kerberos身份验证协议等)。 B…

【教学类-43-03】20231229 N宫格数独3.0(n=1、2、3、4、6、8、9) (ChatGPT AI对话大师生成 回溯算法)

作品展示: 背景需求: 大4班20号说:我不会做这种(九宫格),我做的是小格子的, 他把手工纸翻过来,在反面自己画了矩阵格子。向我展示:“我会做这种!” 原来他会…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(15)

接前一篇文章:《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(14) 1.3 PCI总线的存储器读写总线事务 1.3.4 PCI读写主存储器 前文已提到,由于本节内容较长,因此将后一部分内容放在本文中。 为…

Java多线程技术五——单例模式与多线程

1 概述 本章的知识点非常重要。在单例模式与多线程技术相结合的过程中,我们能发现很多以前从未考虑过的问题。这些不良的程序设计如果应用在商业项目中将会带来非常大的麻烦。本章的案例也充分说明,线程与某些技术相结合中,我们要考虑的事情会…

java注解和反射

java注解和反射 内置注解 Override 重写生命 Deprecated 已过时的方法,不推荐使用,可以使用 SuppressWarning 镇压警告,懂的都懂 元注解 作用:负责注解其他的注解 Target 描述注解的使用范围 Retention 描述注解的生命周期 Docu…

从座舱到跨域融合,老牌汽车零部件厂商如何破局数字化变革

当前,整个汽车供应链正在经历深层次的重构,传统零部件厂商必须加速“自我革新”。 在汽车“新四化”的巨变下,大量传统零部件濒临消失或者减少了需求,传统汽车零部件企业的相关业务开始日益萎缩,生存空间遭受不同程度…

我的128天之创作纪念日

目录 序 机缘 收获 日常 成就 憧憬 序 今天收到CSDN的一条消息推送,“初九之潜龙勿用 ,不知不觉今天已经是你成为创作者的 第128天 啦。。。” 是啊,自今年8月24日开始写文章以来,时间过得好快,无论开心、痛苦…

51单片机之LED灯

51单片机之LED灯 🌴前言:🏮点亮LED灯的原理💘点亮你的第一个LED灯💘点亮你的八个LED灯 📌让LED灯闪烁的原理🎽 LED灯的闪烁🏓错误示范1🏓正确的LED闪烁代码应该是这样&am…

【开源】基于Vue+SpringBoot的公司货物订单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

4.26 构建onnx结构模型-Suqeeze

前言 构建onnx方式通常有两种: 1、通过代码转换成onnx结构,比如pytorch —> onnx 2、通过onnx 自定义结点,图,生成onnx结构 本文主要是简单学习和使用两种不同onnx结构, 下面以 Suqeeze 结点进行分析 方式 方法一…

three.js实现点击选中模型,模型描边高亮效果

射线投射器Raycaster通过.intersectObjects()判断模型是否选中EffectComposer.js进行后期处理&#xff0c;添加描边高亮效果 <template><div class"app"><div ref"canvesRef" class"canvas-wrap"></div></div> &…

Python面向对象编程 —— 类和异常处理

​ &#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 1. 类 1.1 类的定义 1.2 类变量和实例变量 1.3 类的继承 2. 异常处理 2.1类型异常 2.…

【docker实战】安装tomcat并连接mysql数据库

本节用docker来安装tomcat&#xff0c;并用这个tomcat连接我们上一节安装好的mysql数据库 一、拉取镜像 [rootlocalhost data]# docker pull tomcat:8.5.69二、运行tomcat bitnami的tomcat的根目录在/opt/bitnami/tomcat/webapps下面&#xff0c;所以我们为了方便部署我们的…

Springboot整合MybatisPlus的基本CRUD

目录 前言1. 搭建项目2. 基本的CRUD 前言 发现项目框架是MybatisPlus的&#xff0c;由于个人使用该框架的CRUD比较少 对此学习过程中&#xff0c;从零到有开始搭建学习还是比较重要的&#xff0c;感悟会比较多 关于各个类的使用&#xff0c;可看如下文章&#xff1a; 剖析Ja…

DotNet 命令行开发

DotNet 命令行开发 下载安装下载 SDK安装 SDK绿色版下载绿化脚本 常用命令创建 dotnet new运行 dotnet run发布应用 dotnet publish更多命令 VSCode 调试所需插件调试 CS 配置项目.csproj排除依赖关系 launch.jsontasks.json 参考资料 下载安装 下载 SDK 我们就下最新的好&am…