236. 二叉树的最近公共祖先(C++)

文章目录

  • 前言
  • 一、题目介绍
  • 二、解决方案
  • 三、优化
  • 总结


前言

在本篇文章中我们将会讲解二叉树中极为经典的题目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 。因为根据定义最近公共祖先节点可以为节点本身。

我们举几个例子,方便大家更好的理解
在这里插入图片描述
6和7的公共祖先右5,3,但是题目要求我们找最近公共祖先,也就是5.
在这里插入图片描述
7和5的最近公共祖先是5.

同时注意一下提示:
🌟所有 Node.val 互不相同 。
🌟p != q
🌟p 和 q 均存在于给定的二叉树中。

二、解决方案

我们通过分析可以发现这样的规律

一个节点在左子树,一个节点在右子树,这个节点就是最近公共祖先
一个节点是另一个节点的祖先节点,这个祖先节点就是最近公共祖先

我们可以根据这一特性解决这道问题
🌟判断这个节点是不是根节点,如果是我们就返回这个节点。这时这个节点就是另一个节点的祖先
🌟如果两个节点都在左子树,我们就去左子树寻找
🌟如果两个节点都在右子树,我们就去右子树寻找

class Solution {
public:bool IsInTree(TreeNode* root, TreeNode* x){if (root == nullptr){return false;}//前序遍历if (root == x){return true;}if (IsInTree(root->left, x)){return true;}if (IsInTree(root->right, x)){return true;}return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){if (root == nullptr){return nullptr;}//判断这个节点if (root == p || root == q){return root;}bool pInLeft, pInRight, qInLeft, qInRight;pInLeft = IsInTree(root->left, p);pInRight = !pInLeft;qInLeft = IsInTree(root->left, q);qInRight = !qInLeft;//一个在左边,一个在右边,root就是最近公共祖先if ((pInRight && qInLeft) || (qInRight && pInLeft)){return root;}//都在左边,去左子树找if (pInLeft && qInLeft){return lowestCommonAncestor(root->left, p, q);}//都在右边,去右子树找else if (qInRight && pInRight){return lowestCommonAncestor(root->right, p, q);}//找不到return nullptr;}
};

我们看一下时间复杂度:
按照最快情况分析
在这里插入图片描述
1和3的最经公共祖先是13.时间复杂度为O(N*2)

我们能否进行优化呢???

三、优化

我们还有一种解决方案,如果这个节点存了父亲节点,我们就很容易解决这道问题。
转化为:两个链表找交点

但是这道题目没有父亲节点,我们可以转化成求路径
🌟找出两个节点从根节点到这个节点的路径。
🌟路径长的先走差数次
🌟两个路径一起删除节点,最先相同的就是最近公共祖先。

我们通过上帝视角看一下
在这里插入图片描述

找到两条路径
在这里插入图片描述
路径长的先走差数次
在这里插入图片描述
两个路径一起删除节点,最先相同的就是最近公共祖先

在这里插入图片描述

如何查找两条路径??借助栈来实现

进行前序遍历
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码编写

class Solution {
public:bool Route(stack<TreeNode*>& s, TreeNode* root, TreeNode* p){if (root == nullptr){return false;}//先入栈s.push(root);//判断这个节点if (root == p){return true;}//判断左子树if (Route(s, root->left, p)){return true;}//判断右子树if (Route(s, root->right, p)){return true;}//不在左也不再右,从栈里删除这个节点s.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){stack<TreeNode*>s1;stack<TreeNode*>s2;Route(s1, root, p);Route(s2, root, q);//长的先走while (s1.size() != s2.size()){if (s1.size() > s2.size()){s1.pop();}else{s2.pop();}}//一起走while (s1.size()){//相同if (s1.top() == s2.top()){return s1.top();}s1.pop();s2.pop();}return nullptr;}
};

总结

以上就是今天要讲的内容,本文仅仅详细介绍了236. 二叉树的最近公共祖先(的内容。希望对大家的学习有所帮助,仅供参考 如有错误请大佬指点我会尽快去改正 欢迎大家来评论~~ 😘 😘 😘

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何借VR之手,让展厅互动更精彩?

VR虚拟现实技术以其卓越的沉浸式体验为特点&#xff0c;引领用户踏入一个全新的虚拟世界&#xff0c;正因如此&#xff0c;它开始被广泛应用于展厅、商业等多个领域。那么&#xff0c;今天&#xff0c;让我们就来了解一下这种技术是如何为展厅带来精彩互动体验的吧&#xff01;…

日常使用工具(截图,笔记,一键启动)

目录 一,截图 Snipaste 二.笔记 Joplin 三.翻译 四.自动启动软件 这篇记录一下工作中用的很顺手的工具. 一,截图 Snipaste 官网:Snipaste - 截图 贴图 下面是官方手册. 使用 我都是直接F1 就会出现选择框,随意拖动大小,选择下方工具栏,相应位置, 二.笔记 Joplin 官网:…

el-table表格实现鼠标拖动而左右滑动

场景描述&#xff1a; 表格样式较为复杂&#xff0c;10条数据超出整个屏幕的高度&#xff0c;因而导致无法快速拖动滚动条&#xff0c;所以提出需要在表格内容区拖动鼠标&#xff0c;从而实现无需滚动到底部就可以左右拖动表格内容的效果。 具体实现&#xff1a; 实现的方式…

[排序算法]4. 图解堆排序及其代码实现

先来看看什么是堆? 堆是一种图的树形结构&#xff0c;被用于实现“优先队列”&#xff08;priority queues&#xff09; 注:优先队列是一种数据结构&#xff0c;可以自由添加数据&#xff0c;但取出数据时要从最小值开始按顺序取出。 在堆的树形结构中&#xff0c…

.NET 某和OA办公系统全局绕过漏洞分析

转自先知社区 作者&#xff1a;dot.Net安全矩阵 原文链接&#xff1a;.NET 某和OA办公系统全局绕过漏洞分析 - 先知社区 0x01 前言 某和OA协同办公管理系统C6软件共有20多个应用模块&#xff0c;160多个应用子模块&#xff0c;从功能型的协同办公平台上升到管理型协同管理平…

JS-06 原型式继承借用构造函数实现继承

目录 1 原型式继承 场景 前置问题 实现方法 2 借用构造函数实现继承 前置问题 错误的实现方式 正确的实现方式 1 原型式继承 场景 a、创建一个纯洁的对象&#xff1a;对象在控制台打印什么属性都没有 b、创建一个继承自某个父对象的子对象 前置问题 一个对象里有很…

基于稀疏辅助信号平滑的心电信号降噪方法(Matlab R2021B)

基于形态成分分析理论&#xff08;MCA&#xff09;的稀疏辅助信号分解方法是由信号的形态多样性来分解信号中添加性的混合信号成分&#xff0c;它最早被应用在图像处理领域&#xff0c;后来被引入到一维信号的处理中。 在基于MCA稀疏辅助的信号分析模型中&#xff0c;总变差方…

【前端篇】前端开发大厂面试真题

为助力小伙伴们梳理前端知识体系&#xff0c;从而能够充分地做好面试准备&#xff0c;那么今天就来给大家分享一份前端开发的面试真题与相关知识点&#xff0c;其中涵盖了最新版本的八股文&#xff08;包含最新的 Vue 3 面试题&#xff09;、高频算法题以及大佬的面经&#xff…

嵌入式进阶——EEPROM读写

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 设置EEPROM读写String字符串官方示例 EEPROM是一种可擦写可编程只读存储器&#xff08;Electrically Erasable Programmable Read-…

[ARM-2D 专题] arm-2d项目简介

Arm-2D 是一个用于 Cortex-M 处理器上的 2.5D 图像处理的开源项目。 由ARM公司开发和维护&#xff0c;属于官方性质的项目&#xff0c;目前最新版本为V1.1.6. 2022年7月发布1.0的预览版&#xff0c; 2023年2月发布第一个正式版V1.1.1&#xff0c;近一年来快速迭代和功能增强&a…

数据库-SQL优化下

Group by 优化 limit优化 count优化 UPDATE优化 当用id去更改的时候,一个是id1 另一个id2 这是没毛病的&#xff0c;因为加的是行锁 但是如果根据name 一个是where nameaa. 另一个是namehh,在另一个事务没提交前&#xff0c;另一个不能提交&#xff0c;因为name字段不是索引…

数据结构复习指导之B树和B+树

目录 B树和B树 考纲内容 1.B树及其基本操作 1.1B树的查找 1.2B树的高度&#xff08;磁盘存取次数&#xff09; 1.3B树的插入 1.4B树的删除 2.B树的基本概念 B树和B树 考纲内容 考研大纲对 B树和 B树的要求各不相同&#xff0c;重点在于考查B树&#xff0c;不仅要求理解…

基于51单片机数字频率计的设计

本文提出设计数字频率计的方案,重点介绍以单片机AT89C51为控制核心,实现频率测量的数字频率设计。测频的基本原理是采用在低频段直接测频法,在低频段直接测频法的设计思路,硬件部分由单片机和数计显示电路组成;软件部分由信号频率测量模块和数据显示模块等模块实现。应用单…

Raven2掠夺者2渡鸦2账号需要验证怎么解决 超简单验证账号教程

《渡鸦2》是一款源自韩国的创新力作&#xff0c;作为《Raven》系列的最新续篇&#xff0c;这款游戏在MMORPG手游领域内再度扩展了其标志性的暗黑奇幻宇宙&#xff0c;融入了大量革新的游戏设计与丰富内容。定档于2024年5月29日开启公测的《渡鸦2》&#xff0c;正处在紧张刺激的…

美光拟投巨资在日本广岛建DRAM厂,目标2027年底投产

美光科技&#xff08;Micron Technology&#xff09;据日本媒体报道&#xff0c;计划在日本广岛县新建一座DRAM芯片生产工厂&#xff0c;目标最快于2027年底投入运营。这一举措标志着美光在增强其内存芯片生产能力方面的又一重大步伐。 报道称&#xff0c;新工厂的总投资规模预…

Kotlin核心编程知识点-03-类型系统

文章目录 1.null 引用2.可空类型2.1.安全的调用 ?.2.2.Elvis 操作符 ?:2.3.非空断言 !!.2.4.类型检查2.5.类型智能转换 3.比 Java 更面向对象的设计3.1.Any&#xff1a;非空类型的根类型3.2.Any?: 所有类型的根类型3.3.自动装箱和拆箱3.4.数组类型 4.泛型&#xff1a;让类型…

CVPR2024《RMT: Retentive Networks Meet Vision Transformers》论文阅读笔记

论文链接&#xff1a;https://arxiv.org/pdf/2309.11523 代码链接&#xff1a;https://github.com/qhfan/RMT 引言 ViT近年来在计算机视觉领域受到了越来越多的关注。然而&#xff0c;作为ViT的核心模块--自注意力缺乏空间先验知识。此外&#xff0c;自注意力的二次计算复杂度…

Spring和Servlet的整合

Servlet对象是谁创建的&#xff1f; 由服务器端创建的 程序启动调用加载spring配置文件代码 Web应用程序启动也需要加载Spring配置文件 Web开发中有三大组件&#xff1a; 1、servlet 2、filter 3、listener&#xff08;request&#xff0c;session&#xff0c;application&…

如何确保大模型 RAG 生成的信息是基于可靠的数据源?

在不断发展的人工智能 (AI) 领域中&#xff0c;检索增强生成 (RAG) 已成为一种强大的技术。 RAG 弥合了大型语言模型 (LLM) 与外部知识源之间的差距&#xff0c;使 AI 系统能够提供更全面和信息丰富的响应。然而&#xff0c;一个关键因素有时会缺失——透明性。 我们如何能够…

LabVIEW软件需求分析文档内容和编写指南

编写LabVIEW软件需求分析文档&#xff08;Software Requirements Specification, SRS&#xff09;是软件开发的关键步骤之一。以下是详细的内容结构、编写指南和注意事项&#xff1a; 内容结构 引言 项目背景&#xff1a;简要介绍项目背景和目的。 文档目的&#xff1a;说明需…