剑指 Offer 68 - II. 二叉树的最近公共祖先 / LeetCode 236. 二叉树的最近公共祖先(搜索与回溯)

news2024/10/6 16:30:56

题目:

链接:剑指 Offer 68 - II. 二叉树的最近公共祖先;LeetCode 236. 二叉树的最近公共祖先
难度:中等
上一题博客:剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 / LeetCode 235. 二叉搜索树的最近公共祖先(二叉搜索树性质,搜索与回溯)

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

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
在这里插入图片描述

示例 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。因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉树中。

搜索与回溯:

这个就是上一题中的方法二,区别也就是取消了二叉搜索树的设定,变成了普通二叉树。
不考虑二叉搜索树的数值排序性质,直接找 p、q 节点,类似于后序遍历。用一个节点指针 *ans 记录找到的最近公共祖先。对于递归过程中的每个节点,先搜索它的左右子树中有没有 p 和 q ,在搜索左右子树的过程中,如果找到了 p 或 q ,会将 p 或 q 层层回溯传递,而如果已经找到了最近公共祖先ans,则直接将ans回溯传递;然后开始条件判断,如果已经在左右子树的搜索过程中找到了ans,那么直接回溯传递ans,如果root、左子树返回值 l 、右子树返回值 r 中有两个节点分别等于 p 和 q ,说明当前 root 就是最近公共祖先,赋值给 ans 并返回,如果root、l、r 中只有一个等于 p 或 q,则将这个节点回溯传递给上层判断,如果没找到 p 或 q 直接返回空值。

代码:

/**
 * 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 {
private:
    TreeNode *ans = nullptr;  // 最近公共祖先
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == nullptr) return nullptr;
        // 搜索左右子树
        TreeNode* l = lowestCommonAncestor(root->left, p, q);
        TreeNode* r = lowestCommonAncestor(root->right, p, q);
        // 条件判断
        if(ans != nullptr) return ans;
        bool pFound = (root == p || l == p || r == p);
        bool qFound = (root == q || l == q || r == q);
        if(pFound == true && qFound == true) {
            ans = root;
            return ans;
        }
        if(pFound == true) return p;
        if(qFound == true) return q;
        return nullptr;
    }
};

时间复杂度O(N)。
空间复杂度O(N),取决于递归栈空间,在二叉树退化为链表时取得。

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

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

相关文章

python:并发编程(二十四)

前言 本文将和大家一起探讨python并发编程的实际项目:win图形界面应用(篇六,共八篇),系列文章将会从零开始构建项目,并逐渐完善项目,最终将项目打造成适用于高并发场景的应用。 本文为python并…

Pandas进阶修炼120题-第二期(Pandas数据处理,21-50题)

文章目录 Pandas进阶修炼120题第二期 Pandas数据处理21.读取本地EXCEL数据22.查看df数据前5行23.将salary列数据转换为最大值与最小值的平均值方法一:正则表达式(分别使用apply(),applymap(),map()来实现)方法二:apply…

wifi芯片原理

一、在系统中的位置 基带(baseband) 基带的作用有三个: 1、队列包的管理 2、调试解调 3、CSMA/CA机制 CSMA/CA的全称是Carrier Sense Multiple Access with Collision Avoidance,即载波侦听多路访问/冲突避免。 各…

java——集合框架

文章目录 接口实现(类)算法1. 排序算法2. 查找算法3. 拷贝算法4. 填充算法5. 比较算法6. 随机算法7. 迭代器算法8. 交集、并集、差集9. 分割集合10. 数组和集合的互转 集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容&#x…

C++手撕红黑树

目录: 红黑树的概念红黑树的性质红黑树节点的定义 红黑树结构红黑树的插入操作红黑树的验证红黑树的代码实现 红黑树的删除红黑树与AVL树的比较红黑树的应用 总结 红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结…

DevOps系列文章之 Spring Boot Docker打包

应用准备容器化,因为几十个应用从测试到发布太麻烦了,而且还会因为环境的因素导致部署中出现各种问题。为了在开发、测试、生产都能保持一致的环境,就引进了容器技术,而目前常用的应用使用基于spring boot的。 在Spring Boot应用…

AI数字人之语音驱动面部模型及超分辨率重建Wav2Lip-HD

1 Wav2Lip-HD项目介绍 数字人打造中语音驱动人脸和超分辨率重建两种必备的模型,它们被用于实现数字人的语音和图像方面的功能。通过Wav2Lip-HD项目可以快速使用这两种模型,完成高清数字人形象的打造。 项目代码地址:github地址 1.1…

Canal监听MySQL

Canal监听MySQL 1、Mysql数据库开启binlog模式 注意:Mysql容器,此处Mysql版本为5.7 #进入容器 docker exec -it mysql /bin/bash #进入配置目录 cd /etc/mysql/mysql.conf.d #修改配置文件 vi mysqld.cnf(1) 修改mysqld.cnf配置文件,添加如…

Android:安卓开发使用okHttp进行网络请求和MySQL数据库完成图书馆管理系统APP

1、总体目标 1.1 项目概述 项目名称:基于安卓平台的图书管理系统。 本项目旨在研发一个图书管理系统,实现图书馆的信息化管理。在方便用户在线浏览,借阅,归还图书,方便图书馆管理员对图书进行管理。能很好的为用户提…

从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文

1 中断处理程序的基本要求 当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是中断执行完毕后要恢复到原来执行的程序,除了时间流逝外,原来运行的程序应该毫无感知。 具体到Armv…

如何设计一个短信发送功能

本文主要分享了如何设计一个发送短信功能。 一、总结简述 1.梳理多个平台短信API的发送参数,集成封装提供统一的API,支持多个短信平台(阿里云、腾讯云、百度云、京东云、七牛云)灵活切换 2.提供存储方案,表结构设计…

Redis数据库操作

Redis 命令参考 — Redis 命令参考http://doc.redisfans.com/ 1、Redis,远程词典服务器,是一个基于内存的键值型NoSQL数据库 特征: 键值型,支持多种不同数据结构,功能丰富 单线程,每个命令具备原子性 …

C语言督学营(中级阶段)

文章目录 中级阶段9.数据结构概述逻辑结构 与 存储结构时间复杂度、空间复杂度 10.11.12.线性表 (代码实战)线性表的定义、特点1.线性表的顺序存储(顺序表示):顺序表静态分配动态分配顺序表的定义、初始化、插入、删除、按值查找、按位查找 操作 (代码):…

go开发多云资产管理平台

go开发多云资产管理平台cmdb 代码仓库github.com/yunixiangfeng/gocmdb 云主机管理 主机资源监控 开发流程 Welcome to Beego | Beego bee new gocmdb/servercd gocmdb/servergo mod tidygo get -u github.com/beego/beego/v2 go get -u "github.com/astaxie/beego/o…

津津乐道设计模式 - 模版模式详解(以女友化妆流程带你彻底明白)

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》…

JDBC-->java如何连接数据库(详细版小白必备)

个人名片: 🐅作者简介:一名大二在校生,热爱生活,爱好敲码! \ 💅个人主页 🥇:holy-wangle ➡系列内容: 🖼️ tkinter前端窗口界面创建与优化 &…

工业相机——显微镜头/放大镜头

校准尺,最小测量刻度为0.1mm 上图为手机拍的看不清,放了一个网上找的图,校准的详细参数见下图 例如:物距为116mm的显微镜头,这种镜头没有景深,只能测镜头前端到物体116mm的物体 ,几乎没有景深&a…

Vscode配置C/C++环境出现报错,导致不能运行代码,报错如下:

Vscode配置C/C环境出现报错,导致不能运行代码,报错如下: 问题描述—gcc : 无法将“gcc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次…

Hexo博客搭建 —— Next主题配置

Hexo博客搭建 —— Next主题配置 文章目录 Hexo博客搭建 —— Next主题配置配置文件区分站点配置文件主题配置文件 配置文件描述简称引入next主题-sitenext主题页面模式设置-next设置首页不显示全文-site设置博客文章持久化连接-site下载插件URL Setting 参考文档 配置文件区分…

【Docker】一文了解DockerFile

文章目录 Dockerfile 概念DockerFile的指令1、FROM 指定基础镜像2、RUN 执行命令3、COPY 复制文件4、ADD 更高级的复制文件5、ENV 设置环境变量6、EXPOSE7、VOLUME 定义匿名卷8、CMD容器启动命令9、ENTRYPOINT入口点10、USER 指定当前用户11、WORKDIR 指定工作目录12、LABEL为镜…