【LeetCode热题100】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 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:
输入:root = [1,2], p = 1, q = 2
输出:1

提示:

  • 树中节点数目在范围 [2, 105] 内。
  • -109 <= Node.val <= 109
  • 所有 Node.val 互不相同 。
  • p != q
  • p 和 q 均存在于给定的二叉树中。

四.解题思路

想了一种自己比较好理解的方法。
对于当前结点来说,我们要进行以下步骤的判别:

  1. 定义递归函数的返回值为一个pair<bool, bool>,含义是当前结点是否是所给第一个,第二个结点的祖先。
  2. 对于每一个结点root来说,pair<bool, bool> isLeftParent()获取他左孩子的情况,即他的左孩子是否是所给<第一个数,第二个数>的祖先,pair<bool, bool> isRightParent()获取它右孩子的情况。
    在这里插入图片描述
    例如上述二叉树,假设我们要求64的公共最近祖先,采用后序遍历
  3. 对于6来说,我们进行判断,若①他的左孩子或者右孩子中,任意一个为第一个数6的祖先②该结点本身的值和第一个数6相等,只要满足任意一条,就视为该结点是第一个数6的祖先。
  4. 因为结点6没有孩子,所以他的左孩子和右孩子都不可能是所给的6和4的祖先,他的左右孩子返回给他{false, false},{false, false} ,而后判断6本身是否和所给两个数的其中一个相等,这里6 = 所给第一个数,所以这一栈帧中返回{true, false},表示这个结点为根的树中有第一个数的祖先,没有第二个数的祖先。
  5. 其他情况同理,当递归到某一个结点,其既是第一个数又是第二个数的祖先时,我们便找到了公共祖先(这里是5)。

五.代码实现

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {bool result = false;bool left = false;bool right = false;isParent(root, p->val, q->val, result);return ans;}pair<bool, bool> isParent(TreeNode* root, int left, int right, bool &result){//边界if(!root) return {false, false};if(result) return {true, true};//左子树是否是两个数的祖先pair<bool, bool> isLeftParent = isParent(root->left, left, right, result);//右子树是否是两个数的祖先pair<bool, bool> isRightParent = isParent(root->right, left, right, result);//只要这个结点的左子树或右子树有一个是第一个数的祖先,便认为该结点也是这个数的祖先bool l = isLeftParent.first || isRightParent.first;//只要这个结点的左子树或右子树有一个是第二个数的祖先,便认为该结点也是这个数的祖先bool r = isLeftParent.second || isRightParent.second;//再判断该结点本身的值是否和这两个数相等if(l || root->val == left) l = true;if(r || root->val == right) r = true;//如果都满足且尚未找到if(l && r && !result) {	result = true;ans = root;}  return {l, r};}
private:TreeNode* ans =  nullptr;
};

在这里插入图片描述

六.题目总结

对于递归题,先找解题思想(分类讨论),再找边界,再定顺序和微操, 然后验证。

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

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

相关文章

[SpringCloud] Feign Client 的创建 (一) (四)

文章目录 1.FeignClientsRegistrar2.完成配置注册2.1 registerDefaultConfiguration方法2.2 迭代稳定性2.3 registerFeignClients方法 1.FeignClientsRegistrar FeignClientsRegistrar实现ImportBeanDefinitionRegistrar接口。 2.完成配置注册 public void registerBeanDefinit…

浏览器工作原理与实践--作用域链和闭包 :代码中出现相同的变量,JavaScript引擎是如何选择的

在上一篇文章中我们讲到了什么是作用域&#xff0c;以及ES6是如何通过变量环境和词法环境来同时支持变量提升和块级作用域&#xff0c;在最后我们也提到了如何通过词法环境和变量环境来查找变量&#xff0c;这其中就涉及到作用域链的概念。 理解作用域链是理解闭包的基础&#…

Verilog语法之assign语句学习

assign语法主要是对组合逻辑的变量进行赋值的&#xff0c;就是把一个变量赋值给另一个变量&#xff0c;被复制的变量必须是wire类型的参数。 从仿真结果可以看出&#xff0c;data_in变量的值赋值给了data_out,assign语法就是赋值没有任何延迟&#xff0c;data_in是什么值&#…

Java数据结构与集合原码

数据结构与集合原码 文章目录 数据结构与集合原码1. 数据结构基本概念1.1 概念1.2 数据结构的研究对象 2. 常见存储结构2.1 数组2.2 链表2.2.1 单向链表2.2.2 双向链表 2.3 二叉树2.4 栈(stack)2.5 队列 3. 二叉树3.1 二叉树的遍历3.2 经典二叉树 4. List实现类源码分析4.1 Arr…

redis和redisson实现分布式锁

redis和redisson实现分布式锁 基于setnx命令的分布式锁基于set命令的分布式锁redission看门狗分布式锁 基于setnx命令的分布式锁 1. 加锁 使用 Redis 实现分布式锁&#xff0c;最直接的想法是利用 setnx 和 expire 命令实现加锁。 在 Redis 中&#xff0c;setnx 是「set if …

1.排列数组奇数在前偶数在后

文章目录 大家好&#xff0c;我是晓星航。今天为大家带来的是 排列数组奇数在前偶数在后 相关的讲解&#xff01;&#x1f600; public static void swap(int[] array) {int left 0;int right array.length - 1;while (left < right) {while (left < right &&…

IDEA2023版本整合SpringBoot热部署

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…

手撕算法-最小覆盖子串

描述 分析 滑动窗口。 参考力扣官方的题解思路 本问题要求我们返回字符串 s 中包含字符串 t 的全部字符的最小窗口。我们称包含 t 的全部字母的窗口为「可行」窗口。 我们可以用滑动窗口的思想解决这个问题。在滑动窗口类型的问题中都会有两个指针&#xff0c;一个用于「延伸…

javascript基础练习题之渔夫捕鱼

一、题目要求&#xff1a;根据用户输入的年、月、日判断是打鱼还是晒网。代码中使用了isLeapYear函数来判断输入的年份是否为闰年&#xff0c;getDays函数来计算输入日期是一年中的第几天&#xff0c;然后根据计算结果来确定是打鱼还是晒网。最后代码通过弹窗提示用户是打鱼还是…

吴渔夫:AI技术引领游戏产业革命,小团队有大作为

AI技术的突飞猛进&#xff0c;游戏产业正在经历一场前所未有的变革。中国网游先锋&#xff0c;火石控股创始人吴渔夫&#xff0c;近日在接受第一财经日报的采访&#xff0c;对AI在游戏制作中的应用和未来趋势有着深刻的见解。 吴渔夫指出&#xff0c;AI技术的引入极大地降低了游…

游戏推广的新篇章:Xinstall助力实现全渠道效果统计与提升

随着游戏市场的日益繁荣&#xff0c;游戏推广已成为各大游戏公司争夺市场份额的关键环节。然而&#xff0c;面对众多推广渠道和复杂的用户行为&#xff0c;如何精准地评估推广效果、优化投放策略&#xff0c;成为了游戏推广人员亟待解决的问题。此时&#xff0c;Xinstall作为一…

绿岛机械加入2024第13届生物发酵展

参展企业介绍 南京绿岛机械设备有限公司是一家专注于碟式分离机领域的生产服务型企业。公司以多年从事离心分离设备的设计和制造经验为基础&#xff0c;通过产品改良和技术革新&#xff0c;从根本上解决了传统碟式分离设备的固有技术缺陷&#xff0c;增强了控制系统的安全性和…

2024第六届环境科学与可再生能源国际会议能源 (ESRE 2024) 即将召开!

2024第六届环境科学与可再生能源国际会议 能源 &#xff08;ESRE 2024&#xff09; 即将举行 2024 年 6 月 28 日至 30 日在德国法兰克福举行。ESRE 2024 年 旨在为研究人员、从业人员和专业人士提供一个论坛 从工业界、学术界和政府到研究和 发展&#xff0c;环境科学领域的专…

【C++初阶】之类和对象(中)

【C初阶】之类和对象&#xff08;中&#xff09; ✍ 类的六个默认成员函数✍ 构造函数&#x1f3c4; 为什么需要构造函数&#x1f3c4; 默认构造函数&#x1f3c4; 为什么编译器能自动调用默认构造函数&#x1f3c4; 自己写的构造函数&#x1f3c4; 构造函数的特性 ✍ 拷贝构造…

在Windows系统上安装多个 Nodejs

前言 在Windows系统安装Nodejs 在Windows系统上安装多个 Nodejs v14.16.1安装位置 D:\sde\nodejs\node-v14.16.1-win-x64 v16.20.2安装位置 D:\sde\nodejs\node-v16.20.2-win-x64 v18.20.0安装位置 D:\sde\nodejs\node-v18.20.0-win-x64 v20.12.0安装位置 D:\sde\nod…

Java毕业设计-基于springboot开发的游戏分享网站平台-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台登录2.1管理员功能模块2.2用户功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发的…

ChatGLM2本地部署方法

chatglm2部署在本地时&#xff0c;需要从huggingface上下载模型的权重文件&#xff08;需要科学上网&#xff09;。下载后权重文件会自动保存在本地用户的文件夹上。但这样不利于分享&#xff0c;下面介绍如何将chatglm2模型打包部署。 一、克隆chatglm2部署 这个项目是chatgl…

“李子园”上榜中国民营企业社会责任优秀案例

日前&#xff0c;由浙江省工商联、浙江工商大学主办&#xff0c;杭州市工商联协办的2024浙江民营企业社会责任暨浙商ESG研讨会在杭州召开&#xff0c;探索民营企业履行社会责任的方法路径和趋势。会上公布了2023年中国民营企业社会责任优秀案例&#xff08;浙江入选企业&#x…

【小尘送书-第十五期】Excel函数与公式应用大全for Excel 365 Excel

大家好&#xff0c;我是小尘&#xff0c;欢迎你的关注&#xff01;大家可以一起交流学习&#xff01;欢迎大家在CSDN后台私信我&#xff01;一起讨论学习&#xff0c;讨论如何找到满意的工作&#xff01; &#x1f468;‍&#x1f4bb;博主主页&#xff1a;小尘要自信 &#x1…

【Linux】对进程地址空间的理解

一、关于进程地址空间的简单理解 进程地址空间其实是分了很多个区域的&#xff0c;区域划分的本质就是区域内的各个地址都是可以使用的。如同下面这个图所示&#xff1a; 无论是环境变量的地址还是环境变量表的地址&#xff0c;所存放的地址都在栈的上部。这里的已初始化数据和…