LeetCode235. 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先
文章目录
- [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)
- 一、题目
- 二、题解
- 方法一:递归
- 方法二:迭代
一、题目
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
二、题解
方法一:递归
我们需要充分利用二叉搜索树的性质,即左子树的所有节点值都小于根节点值,右子树的所有节点值都大于根节点值。这个性质可以帮助我们有效地缩小搜索范围。
算法思路
-
首先,我们要考虑一种简单情况:如果根节点的值大于节点 p 和 q 的值,那么说明 p 和 q 位于根节点的左子树中,因为左子树的所有节点值都小于根节点值。我们可以在根节点的左子树上继续搜索 p 和 q 的最近公共祖先。
-
同样,如果根节点的值小于节点 p 和 q 的值,那么说明 p 和 q 位于根节点的右子树中,因为右子树的所有节点值都大于根节点值。我们可以在根节点的右子树上继续搜索 p 和 q 的最近公共祖先。
-
但是,如果根节点的值介于节点 p 和 q 的值之间,或者根节点的值等于其中一个节点的值,那么说明 p 和 q 分别位于根节点的左右子树中,此时根节点就是它们的最近公共祖先。
-
我们可以利用递归来实现这个过程,根据上述的思路,递归搜索左子树和右子树,最终找到最近公共祖先。
具体实现
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == nullptr) return nullptr;if (root->val > p->val && root->val > q->val) {TreeNode* left = lowestCommonAncestor(root->left, p, q);return left;}if (root->val < p->val && root->val < q->val) {TreeNode* right = lowestCommonAncestor(root->right, p, q);return right;}return root;}
};
算法分析
时间复杂度
- 在每个递归步骤中,我们都会根据节点的值来决定是继续在左子树搜索还是在右子树搜索,所以每次递归都会剔除一半的节点。因此,算法的时间复杂度为 O(log N),其中 N 是树中节点的总数。
空间复杂度
- 递归调用栈的最大深度取决于树的高度,对于平衡的二叉搜索树,空间复杂度为 O(log N);对于不平衡的树,最坏情况下的空间复杂度为 O(N),其中 N 是树中节点的总数。
方法二:迭代
简单来说,就是把上面的递归思路用迭代方式写一遍:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {while(root){if(root->val > p->val && root->val > q->val){root = root->left;}else if(root->val < p->val && root->val < q->val){root = root->right;}else{return root;}}return root;}
};
相关文章:
LeetCode235. 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一:递归方法二:迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…...
设计模式——建造者(Builder)模式
建造者模式(Builder Pattern),又叫生成器模式,是一种对象构建模式 它可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。建造者模式是一步一步创建一个复杂的对象,…...
Java课题笔记~ SpringBoot概述
问题导入 学习了SpringBoot入门案例之后,感觉对比SpringMVC哪一个更加方便简洁? SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程 Spring程序缺点 配置繁琐 依赖设置繁琐 SpringBoot程序…...
python优雅地爬虫!
背景 我需要获得新闻,然后tts,在每天上班的路上可以听一下。具体的方案后期我也会做一次分享。先看我喜欢的万能的老路:获得html内容-> python的工具库解析,获得元素中的内容,完成。 好家伙,我知道我爬…...
UVM RAL后门访问配置
先给一下大致的代码结构,根据代码结构来描述。 //dut结构 module my_dut(...);my_reg U_REG(......);endmodulemodule my_reg(...);//reg1和reg2是一个reg的两个field,reg3单独是一个regreg [15:0] reg1_q;reg [15:0] reg2_q;reg [31:0] reg3_q;endmodu…...
数学建模之“灰色预测”模型
灰色系统分析法在建模中的应用 1、CUMCM2003A SARS的传播问题 2、CUMCM2005A长江水质的评价和预测CUMCM2006A出版社的资源配置 3、CUMCM2006B艾滋病疗法的评价及疗效的预测问题 4、CUMCM2007A 中国人口增长预测 灰色系统的应用范畴大致分为以下几方面: (1)灰色关…...
深入探讨 Oxigen:Rust 实现的并行遗传算法框
第一部分:引言及Oxigen框架概览 随着遗传算法在许多领域(如优化、机器学习和人工智能)的应用日益增多,其性能和效率成为了关键焦点。Oxigen 是一个用 Rust 语言实现的并行遗传算法框架,其提供了高效的并行计算机制&am…...
Flink-----Standalone会话模式作业提交流程
1.Flink的Slot特点: 均分隔离内存,不隔离CPU可以共享:同一个job中,不同算子的子任务才可以共享同一个slot,同时在运行的前提是,属于同一个slot共享组,默认都是“default”2.Slot的数量 与 并行度 的关系 slot 是一种静态的概念,表示最大的并发上线并行度是个动态的概念…...
算法与数据结构(七)--堆
一.堆 1.堆的定义 堆是计算机科学中一类特殊的数据结构的通常,堆通常可以被看做是一颗完全二叉树的数组对象。 堆的特性 1.它是完全二叉树,除了树的最后一层结点不需要是满的,其他的每一层从左到右都是满的,如果最后一层结点不…...
软件工程概述-架构师(三)
软件工程概述(老版) 软件开发生命周期: 软件定义时期:包括 可行性研究和详细需求分析过程,任务是软件工程必需完成的目标,具有可行问题分析、可行性研究、需求分析等。软件开发时期:软件的 设…...
华为手机Outlook手机APP无法登录邮箱,提示[2002]错误代码
近期遇到不少华为手机的Outlook APP无法登录邮箱Office365邮箱的案例,并且提示: 错误 出错了。[2002] 经测试,这应该是华为应用市场下载的Outlook版本有问题。 解决方法: 把Outlook卸载之后从微软官网重新下载官网版本去安装&am…...
“深入探究JVM内部结构与工作原理:解析Java虚拟机“
标题:深入探究JVM内部结构与工作原理 摘要:本文将深入探究Java虚拟机(JVM)的内部结构与工作原理。我们将介绍JVM的基本组成部分,包括类加载器、运行时数据区和执行引擎。同时,我们将通过一个示例代码来说明…...
windows下redis服务启动及.bat文件中中redis服务的启动
windows windows下redis服务的启动 1、不配置环境变量 找到redis服务的安装目录进入命令行窗口并输入命令redis-server.exe redis.windows.conf2、配置环境变量 将redis安装目录配置在path环境变量中之后就可以在cmd窗口的任意位置输入redis-server命令就可以启动redis服务…...
【学习笔记之vue】 Cannot find module ‘node-sass‘
Cannot find module node-sass方案一(不通) 下载node-sass组件 >> npm install -g cnpm>>cnpm install node-sass下载时报错 方案二 使用npm下载node-sass组件 >>npm install node-sassok...
POSTGRESQL 关于安装中自动启动的问题 详解
开头还是介绍一下群,如果感兴趣Polardb ,mongodb ,MySQL ,Postgresql ,redis ,SQL SERVER ,ORACLE,Oceanbase 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加 liuaustin3微信号 &…...
Java寻找数组的中心下标
目录 1.题目描述 2.题解 分析 具体实现 1.题目描述 给你一个整数数组 nums ,请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端,那么左侧数之和…...
ORACLE中判断表是否存在再删除表避免报错与MySql和SqlServer的不同
不同数据库中drop a table if it exists的不同: In MySQL it is pretty easy to drop a table if it exists already. In Oracle and Microsoft’s SQL Server it is a little more complicated. Today I want to present you the solutions for these two DBMS’.…...
解决 Maven 创建 Spring Boot 项目时出现 “Cannot access alimaven“ 错误的方法
系列文章目录 文章目录 系列文章目录前言一、确认 Maven 配置二、创建 Spring Boot 项目三、修改项目的 Maven 配置四、清除 Maven 本地仓库五、重新构建项目总结前言 Maven 是 Java 项目的构建工具,而 Spring Boot 则是用于快速构建 Spring 应用程序的框架。但有时,在创建 …...
设计模式——适配器模式
引入实例 说起适配器其实在我们的生活中是非常常见的,比如:学校的宿舍的电压都比较低,而有的学生想使用大功率电器,宿舍的就会跳闸,然而如果你使用一个适配器(变压器)就可以使用了(…...
如何区分闰年与平年
首先要明白 地球绕太阳运行周期为365天5小时48分46秒(合365.24219天),即一回归年(tropical year)。公历的平年只有365日,比回归年短约0.2422 日,每四年累积约一天,把这一天加于2月末…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
工厂方法模式和抽象工厂方法模式的battle
1.案例直接上手 在这个案例里面,我们会实现这个普通的工厂方法,并且对比这个普通工厂方法和我们直接创建对象的差别在哪里,为什么需要一个工厂: 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类: 两个发…...
window 显示驱动开发-如何查询视频处理功能(三)
D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针,该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...
Java严格模式withResolverStyle解析日期错误及解决方案
在Java中使用DateTimeFormatter并启用严格模式(ResolverStyle.STRICT)时,解析日期字符串"2025-06-01"报错的根本原因是:模式字符串中的年份格式yyyy被解释为YearOfEra(纪元年份),而非…...
