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; 实现的方式…

上海云管平台怎么样?客服电话多少?

云计算已经成为了企业数字化转型的重要一部分&#xff0c;而在上海&#xff0c;云管平台发展更是大势所趋。这不不少小伙伴在问&#xff0c;上海云管平台怎么样&#xff1f;客服电话多少&#xff1f; 上海云管平台怎么样&#xff1f;客服电话多少&#xff1f; 【回答】&#…

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

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

vscode的使用 ubuntu入门之二十二

高亮标识符&#xff0c;变量或者函数可以用 rainbow-highlighter 这个插件 Press shiftaltz, and variables curser is on will be highlighted. Press the same command again to remove highlights. Press shiftalta to remove all highlights. 参考&#xff1a; 在VSCode…

【台阶问题】

目录 问题&#xff1a; 思路&#xff1a; 回溯-分支限界法 知识点 目标函数&#xff08;分支结束的情况&#xff09;: n0 约束函数&#xff08;截断不合理的分支&#xff09;: num < 2 、 i > n-i && num 0 限界函数&#xff08;阶段不最优的分支&#xf…

开发问题合集(待补充)

docker 学习文档 ollama 官网 streamlit 官方文档

通过伪造NPU设备,让AscendSpeed在没有安装torch_npu的环境中跑起来

通过伪造NPU设备,让AscendSpeed在没有安装torch_npu的环境中跑起来 代码输出 背景: 我想在GPU上运行AscendSpeed框架,因为没有torch_npu、deepspeed_npu,又不想一个个注释掉 方法: 1.本文本通过创建一个FakeDevice 类来伪造 NPU&#xff08;Neural Processing Unit&#xff0…

C语言动态内存分配

有些情况下需要开辟的空间大小在程序运行过程中才能确定下来&#xff0c;而常规的在栈区开辟空间是在编译时就分配好了内存&#xff0c;并且内存大小不能改变&#xff0c;因此需要引入动态内存分配&#xff0c;动态内存分配的内存是在堆区&#xff0c;需要由用户手动开辟&#…

共享内存的分享

共享内存是一种进程间通信&#xff08;IPC&#xff0c;Inter-Process Communication&#xff09;的机制&#xff0c;用于在不同进程之间共享数据。它允许多个进程访问同一个内存段&#xff0c;从而使数据传递更加高效。共享内存的主要作用包括&#xff1a; 1. 高效数据交换 共…

java: 警告: 源发行版 8 需要目标发行版 8

前言 该文章中项目背景是&#xff1a;IDEA与设置的版本与实际电脑配置的不一致。也就是说只改了这个团队项目的JDK版本&#xff0c;IDEA上其它项目JDK版本未更改。 提示&#xff1a; IDEA警告&#xff1a;javaX&#xff1a;警告&#xff1a;源发行版 需要目标发行版 简略步…

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

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

qt 笔记

外部进程嵌入到Qt进程界面 将外部进程嵌入到 Qt 进程的界面中是一项复杂的任务&#xff0c;因为它涉及到操作系统特定的细节。在不同的操作系统上&#xff0c;这种嵌入方式可能会有所不同。以下是一些可能的方法和步骤&#xff0c;针对常见操作系统&#xff08;如 Windows 和 …

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

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

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

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

Python面试宝典:Python中与爬虫基础以及数据抓取和解析相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第十七章:Python爬虫:第一节:爬虫基础以及数据抓取和解析】 第十七章:Python爬虫第一节:爬虫基础以及数据抓取和解析1. HTTP协议2. HTML/CSS/JavaScript3. 解析库4. Web开发者工具5.…

Python - list (append, extend, split)

Python list 与 Java 数组 Python list使用[]包裹&#xff0c;类似于Java 数组。不同点在于Python list元素可以是任意类型&#xff0c;Java 数组元组只能是基本数据类型之一。 >>> a [a, 2, [1,2]] >>> type(a) <class list> Python 声明了列表a&…

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

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

嵌入式进阶——EEPROM读写

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