【力扣题解】P236-二叉树的最近公共祖先-Java题解

花无缺

👨‍💻博客主页:@花无缺
欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!
本文由 花无缺 原创

收录于专栏 【力扣题解】


文章目录

  • 【力扣题解】P236-二叉树的最近公共祖先-Java题解
    • 🌏题目描述
    • 💡题解
    • 🌏总结


【力扣题解】P236-二叉树的最近公共祖先-Java题解

P236-二叉树的最近公共祖先

🌏题目描述

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

百度百科中最近公共祖先的定义为:“对于有根树 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
  • pq 均存在于给定的二叉树中。

💡题解

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {// 空树, 返回 null// 当前节点是 p 节点, 那么直接返回 p, 说明 p 就是 p, q 的祖先节点// 当前节点是 q 节点, 那么直接返回 q, 说明 q 就是 p, q 的祖先节点if (root == null || root == p || root == q) {return root;}// 递归遍历左子树和右子树// 搜索左子树和右子树中是否有 p 或 qTreeNode left = lowestCommonAncestor(root.left, p, q);TreeNode right = lowestCommonAncestor(root.right, p, q);// 如果左右子树的搜索结果都不为空, 说明 p 和 q 都在左右子树中找到了// 当前节点肯定就是 p, q 的祖先节点, 直接返回 rootif (left != null && right != null) {return root;}// 如果 left 为空, right 不为空, 那么祖先节点就在右子树中// 结果就是 right, 直接返回if (left == null && right != null) {return right;//     如果 left 不为空, right 为空, 那么祖先节点就在左子树中//     直接返回 left} else if (left != null && right == null) {return left;//     否则 left 和 right 都为空//     说明没有找到公共祖先, 返回 null} else {return null;}
}

时间复杂度:O(n),要搜索整个二叉树,遍历所有节点,节点数为 n。

🌏总结

这个题目要求我们查找两个节点的最近公共祖先节点,那么我们肯定需要自底向上的搜索节点,因为只有自底向上的搜索才会找到两个节点最近的公共祖先节点,那么我们就想到了回溯,先遍历最底层的节点,如果不满足条件,再回溯到上层的节点查找,那么我们就可以使用后序遍历(左右中),后序遍历就是很自然的回溯过程。

此处我们使用的是递归的写法,那么递归的终止条件如何确定呢?首先假设我们从根节点开始出发,如果当前节点是空节点,说明这是一棵空树,那么递归肯定要终止,并且返回 null。另外,如果根节点就是 p 节点或者 q 节点,那么 p 和 q 的公共祖先节点就是根节点,因为如果根节点就是 p(q),那么另外一个节点 q(p)肯定就是当前节点(根节点)的子节点,所以根节点就是公共祖先节点。

所以递归的终止条件为:

// 空树, 直接返回 null
if (root == null) {return null;
}
// 当前节点是 p 节点, 那么直接返回 p, 说明 p 就是 p, q 的祖先节点
// 当前节点是 q 节点, 那么直接返回 q, 说明 q 就是 p, q 的祖先节点
if (root == p || root == q) {return root;
}

接下来我们就要进行后序遍历了,先遍历左子树,再遍历右子树:

而且我们要将左右子树递归的结果保存下来,因为在回溯到中间节点的时候,我们需要使用左右子树递归的结果。

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

然后遍历中间节点:

如果说左右子树返回的结果都不为空,那么说明左右子树都分别找到了 p 和 q 节点,那么说明当前节点就是他们的最近公共祖先节点。

如果有一个子树的结果为空,那么说明他们的祖先节点就在另一棵子树,那么直接返回另一棵子树的结果。

如果两棵树都为空,那么说明搜索完了整棵树都没有找到符合题意的公共祖先,直接返回 null;

// 如果 left 为空, right 不为空, 那么祖先节点就在右子树中
// 结果就是 right, 直接返回
if (left == null && right != null) {return right;
//     如果 left 不为空, right 为空, 那么祖先节点就在左子树中
//     直接返回 left
} else if (left != null && right == null) {return left;
//     否则 left 和 right 都为空
//     说明没有找到公共祖先, 返回 null
} else {return null;
}

作者:花无缺(huawuque404.com)


🌸欢迎关注我的博客:花无缺-每一个不曾起舞的日子都是对生命的辜负~
🍻一起进步-刷题专栏:【力扣题解】
🥇往期精彩好文:
📢【全网最全爱心代码仓库】
📢【CSS选择器全解指南】
📢【HTML万字详解】
你们的点赞👍 收藏⭐ 留言📝 关注✅
是我持续创作,输出优质内容的最大动力!
谢谢!

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

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

相关文章

sqlserver根据分组的内容分别查询出匹配的一条信息

需求场景&#xff1a; 我写了条分组语句&#xff0c; select name from car_machine_command group by name 然后该表有很多条相关的数据&#xff0c;我只想拿各个分组的一条数据看看即可 解决&#xff1a;可以使用窗口函数&#xff08;Window Function&#xff09;和 ROW_NU…

Qt6.5类库详解:QComboBox

哈喽大家好&#xff0c;欢迎关注公众号(20YC编程)&#xff0c;有免费C视频课程哦&#xff01; -今日内容- 1. QComboBox介绍 QComboBox是一个下拉列表框组件类&#xff0c;它提供了一个下拉列表供用户选择&#xff0c;也可以直接当作一个QLineEdit用作输入。 QComboBox除了显…

process.cwd() 与 __dirname 的区别

Node.js 中的 __dirname 和 process.cwd() 都是用于获取文件系统路径的全局变量和方法&#xff0c;但它们有不同的含义和用途。 一、process.cwd() process.cwd() 是一个方法&#xff0c;用于获取 Node.js 进程的当前工作目录。它返回的是 Node.js 进程启动时所在的工作目录的…

bootstrap5实现通用果蔬网站 FoodMart页面模板

一、需求分析 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。它将不同种类的新鲜水果、蔬菜、干果、坚果等聚集在一起&#xff0c;为消费者提供方便、快捷的购物渠道。通用果蔬网站的作用主要包括以下几个方面&#xff1a; 商品展示和销售&#xff1a;通用果蔬网…

arduino ESP32 002 wokwi在线仿真点亮小灯

wokwi 点亮小灯 ESP-IDF #include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h"#define PIN_LED_1 GPIO_NUM_16void setup() {// 设置LED引脚为输出gpio_reset_pin(PIN_LED_1);// esp…

Linux操作系统基础(3):Linux终端的使用

1. Linux终端的介绍 Linux 终端是指在 Linux 操作系统下用于与用户进行交互的命令行界面&#xff08;基于文本的交互&#xff09;。它是用户与操作系统进行直接交互的主要方式&#xff0c;可以通过输入命令来执行各种操作&#xff0c;如文件管理、进程控制、系统配置等。 Lin…

CSS与JavaScript的简单认识

CSS&#xff1a;是一门语言&#xff0c;用于控制网页表现&#xff0c;让页面更好看的。 CSS&#xff08;Cascading Style Sheet&#xff09;&#xff1a;层叠样式表 CSS与html结合的三种方式&#xff1a; 1、内部样式&#xff1a;用style标签&#xff0c;在标签内部定义CSS样式…

竞赛保研 基于机器视觉的手势检测和识别算法

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng…

【C++核心编程(二)】

一、类和对象 C面向对象的三大特性为:封装、继承、多态。 C认为万事万物都皆为对象&#xff0c;对象上有其属性和行为。 例如: 人可以作为对象&#xff0c;属性有姓名、年龄、身高、体重...&#xff0c;行为有走、跑、跳、吃饭、唱歌... 车也可以作为对象&#xff0c;属性…

Git(1):Git概述

1 开发中的实际场景 场景一&#xff1a;备份 小明负责的模块就要完成了&#xff0c;就在即将Release之前的一瞬间&#xff0c;电脑突然蓝屏&#xff0c;硬盘光荣牺牲&#xff01;几个月来的努力付之东流 场景二&#xff1a;代码还原 这个项目中需要一个很复杂的功能&#x…

为自己办一场个展和你的2023告别,上传图片就能生成720云3D线上展厅

来和你的2023告个别吧。只需上传图片并选择一个漂亮的3D展厅&#xff0c;就能生成你的专属展览。在这里&#xff0c;你可以回顾手机里的精彩瞬间&#xff0c;分享你的美好生活或是你的摄影大片、书画作品&#xff0c;也可以是任何值得纪念的瞬间。 通过720云3D空间漫游模板&…

「许战海战略文库」调味品新锐品牌松鲜鲜如何应对竞争

我国调味品市场品牌众多&#xff0c;根据年营收情况可以划分为4个梯队。第一梯队是以海天、李锦记为代表&#xff0c;营收规模超过150亿;第二梯队的代表为中炬高新、老干妈&#xff0c;营收规模为30-150亿不等;第三阶梯是以加加食品、恒顺醋业为代表的企业&#xff0c;总营收不…