力扣:236.二叉树的最近公共祖先(C++)

文章目录

  • 1. 题目描述
  • 2. 题目解析
    • 2.1 思路一
    • 2.1 思路二

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
题目来源: 力扣…二叉树的最近公共祖先

1. 题目描述

百度百科中最近公共祖先的定义为:“对于有根树 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 。因为根据定义最近公共祖先节点可以为节点本身。

提示:

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

2. 题目解析

2.1 思路一

判断p q是否分别在当前节点左右子树中或者其中一个就是树的根。
我们可以通过递归来实现这个过程。具体思想是:

  1. 如果当前节点是其中一个目标节点,则直接返回当前节点。
  2. 如果在当前节点的左右子树中分别找到目标节点,说明当前节点就是最近公共祖先。
  3. 否则 p q都在当前节点的左子树或者右子树中,因此在左子树和右子树中继续递归查找。
    在这里插入图片描述

代码如下:

//判断节点x是否在树中
bool InTree(TreeNode* root, TreeNode* x)
{
    if (root == nullptr) return false;
    if (root == x) return true;
    return InTree(root->left, x) || InTree(root->right, x);
}
reeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
{
	//当前节点是其中一个目标节点,则直接返回当前节点
    if (root == p || root == q) return root;
    //去当前左子树中查找p节点
    bool pInLeft = InTree(root->left, p);
    //在左子树中就不在右子树,因此对pInLeft取反,就是其是否在右子树中的情况
    bool pInRight = !pInLeft;
    //对q节点和对p节点一样
    bool qInLeft = InTree(root->left, q);
    bool qInRight = !qInLeft;
	//在当前节点的左右子树中分别找到目标节点,说明当前节点就是最近公共祖先
    if ((pInLeft && qInRight) || (qInLeft && pInRight))
    {
    	return root;
    } 
    else if (pInLeft && qInLeft)
    {
    	//p q都在当前节点的左子树中,因此在左子树中继续递归查找
    	return lowestCommonAncestor(root->left, p, q);
    } 
    else 
    {
    	//p q都在当前节点的右子树中,因此在右子树中继续递归查找
    	return lowestCommonAncestor(root->right, p, q);
    }
}

2.1 思路二

通过找到从根节点到目标节点的路径,然后将其转换成链表相交问题。
这种方法的步骤如下:

  1. 找到根节点到p节点的路径。
  2. 找到根节点到q节点的路径。
  3. 找到这两条路径的最后一个公共节点。

画个图理解一下:

在这里插入图片描述
代码如下:

//找根节点到节点x的路径
 bool GetPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& st)
    {
        if (root == nullptr) return false;
        st.push(root);
        if (root == x) return true;
        if (GetPath(root->left, x, st))
        {
            return true;
        }
        if (GetPath(root->right, x, st))
        {
            return true;
        }
        st.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        stack<TreeNode*> pPath, qPath;
        GetPath(root, p, pPath);//找到根节点到p节点的路径。
        GetPath(root, q, qPath);//找到根节点到q节点的路径。
        //路径长的先走,直到路径一样长
        while (pPath.size() != qPath.size())
        {
            if (pPath.size() > qPath.size())
            {
                pPath.pop();
            }
            else
            {
                qPath.pop();
            }
        }
        //找这两条路径的最后一个公共节点
        while (pPath.top() != qPath.top())
        {
            pPath.pop();
            qPath.pop();
        }
        return pPath.top();
    }

至此,本片文章就结束了,若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第四十一天 | 理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

理论基础 代码随想录 视频&#xff1a;从此再也不怕动态规划了&#xff0c;动态规划解题方法论大曝光 &#xff01;| 理论基础 |力扣刷题总结| 动态规划入门_哔哩哔哩_bilibili 动归五部曲 1.dp数组以及下标的含义 2.递推公式 3.dp数组如何初始化 4.遍历顺序(例如先背包再…

ue的event dispatch.操作步骤,最详细了

功能&#xff1a;按下键盘1&#xff0c;send方监控键盘事件&#xff0c;recv方打印success Dispatch 间接通信 示例&#xff1a;1.发送方按下键盘1。2.接收方打印success 蓝图很简单&#xff1a; 发送方 接收方 具体操作步骤如下&#xff1a; 1.场景发送方运行监听键盘 2.接受…

Seurat Dimplot函数学习总结

今天为了画这个cluster中怎么显示标签的图&#xff0c;研究了一个Seurat中怎么画这个图的&#xff0c;下面是学习过程中做的总结 运行例子 rm(listls()) library(Seurat) library(SeuratData) library(ggplot2) library(patchwork) pbmc3k.final <- LoadData("pbmc3k…

学浪的缓存怎么导出来

学浪的缓存导出问题困扰着许多用户&#xff0c;备份和管理数据变得至关重要。在数字化时代&#xff0c;保护和利用数据是企业和个人不可或缺的需求。在这篇文章中&#xff0c;我们将深入探讨学浪缓存导出的方法&#xff0c;为您解决疑惑&#xff0c;让您轻松掌握数据的安全与便…

自定义类型详解(结构体,位段,枚举,联合体)

目录 结构体 结构体的自引用 匿名结构体 结构体内存对齐 结构体内存对齐的意义 修改默认对齐数 位段 位段的内存分配 位段的跨平台问题 位段的应用 枚举 枚举类型的定义 枚举和#define的区别 联合体&#xff08;共用体&#xff09; 联合体大小的计算 结构体 C语…

斐讯N1刷OpenWRT并安装内网穿透服务实现远程管理旁路由

文章目录 前言1. 制作刷机固件U盘1.1 制作刷机U盘需要准备以下软件&#xff1a;1.2 制作步骤 2. N1盒子降级与U盘启动2.1 N1盒子降级2.2 N1盒子U盘启动设置2.3 使用U盘刷入OpenWRT2.4 OpenWRT后台IP地址修改2.5 设置旁路由&无线上网 3. 安装cpolar内网穿透3.1 下载公钥3.2 …

08Django项目--用户管理系统--查(前后端)

对应视频链接点击直达 TOC 一些朋友加我Q反馈&#xff0c;希望有每个阶段的完整项目代码&#xff0c;那从今天开始&#xff0c;我会上传完整的项目代码。 用户管理&#xff0c;简而言之就是用户的增删改查。 08项目点击下载&#xff0c;可直接运行&#xff08;含数据库&…

3个完美恢复方案!苹果手机恢复视频就是这么简单

在日常生活中&#xff0c;我们使用苹果手机记录了许多珍贵的视频&#xff0c;包括家庭聚会、旅行经历等。但是我们不小心删除了&#xff0c;在“最近删除”文件夹中也找不到。 别担心&#xff0c;这并不困难&#xff01;无论您是意外删除了重要的视频还是遇到了其他数据丢失问…

PawSQL: 企业级SQL审核工具的新玩家

随着数据库应用在企业中的广泛使用&#xff0c;确保SQL代码质量的重要性日益凸显。现有的SQL审核工具很多&#xff0c;包括Yearning、goInception、Bytebase、爱可生的SQLE、云和恩墨的SQM等等&#xff0c;但是它们或者规则覆盖度、或者是在正确率等方面存在明显不足&#xff1…

【stm32】江科协听课笔记

[3-1] GPIO输出_哔哩哔哩_bilibili 5.GPIO输出 这里&#xff0c;寄存器就是一段特殊的存储器&#xff0c;内核可以通过APB2总线队寄存器进行读写&#xff0c;这样就可以完成输出/读取电平的功能。寄存器的每一位对应一个引脚&#xff0c;stm32是32位的&#xff0c;这里的寄存器…

K8S有了Service,为什么还要Ingress?

1、有了Service为什么还要Ingress? NodePort对外暴露端口存在的不足&#xff1a; 一个端口只能一个服务使用, 端口需要提前规划。 随着业务扩展, 端口的管理将是一个头疼的问题 只支持4层的负载均衡 LoadBalancer存在的不足&#xff1a; 贵、贵、贵。 要上云(俗话说上云…

前端Vue自定义顶部搜索框:实现热门搜索与历史搜索功能

前端Vue自定义顶部搜索框&#xff1a;实现热门搜索与历史搜索功能 摘要&#xff1a; 随着前端开发复杂性的增加&#xff0c;组件化开发成为了提高效率和降低维护成本的有效手段。本文介绍了一个基于Vue的前端自定义顶部搜索框组件&#xff0c;该组件不仅具备基本的搜索功能&am…

Android端 可使用Yolov5训练 路标识别

相信大家对于路标识别&#xff0c;红绿灯识别&#xff0c;图形识别opencv中也是一件烦人的事情&#xff0c;其参数是及其受到现实环境因素的影响的&#xff0c;那么今天我就给大家推荐一种方式&#xff0c;缺点是周期长&#xff0c;但其优点是如果训练效果好久对于环境的各种变…

安卓开发日志采集和分析面面谈

日志面面谈 为什么需要日志 复现问题&#xff0c;回溯到问题产生时候的系统状态&#xff0c;有利于定位和分析问题。 安卓日志有哪些&#xff1f; cpu 关注的纬度&#xff1a; 单个应用使用系统cpu分配温度 有什么用&#xff1a; App卡顿、ANRApp异常退出 怎么用&…

记一次 .NET某企业数字化平台 崩溃分析

一&#xff1a;背景 1. 讲故事 前些天群里有一个朋友说他们软件会偶发崩溃&#xff0c;想分析看看是怎么回事&#xff0c;所幸的是自己会抓dump文件&#xff0c;有了dump就比较好分析了&#xff0c;接下来我们开始吧。 二&#xff1a;WinDbg 分析 1. 程序为什么会崩溃 win…

从0开始回顾ElasticSearch

1 elasticsearch概述 1.1 elasticsearch简介 官网: https://www.elastic.co/ ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的…

芯课堂 | 芯片抗干扰测试方案

MCU芯片对所在环境中存在的电磁干扰须具有一定程度的抗扰度&#xff0c;确保使用该芯片的设备能正常运行。国际电工委员会&#xff08;IEC&#xff09;制定了多项国际标准&#xff0c;其中与MCU芯片相关的有IEC61000-4-2 &#xff08;静电&#xff09;&#xff0c; IEC61000-4-…

RK3568笔记二十六:音频应用

若该文为原创文章&#xff0c;转载请注明原文出处。 一、介绍 音频是我们最常用到的功能&#xff0c;音频也是 linux 和安卓的重点应用场合。 测试使用的是ATK-DLR3568板子&#xff0c;板载外挂RK809 CODEC芯片&#xff0c;RK官方驱动是写好的&#xff0c;不用在自己重新写。…

家居的3D交互展示用什么工具比较专业?

家居的3D交互展示可以使用多种专业工具来实现&#xff0c;这些工具不仅能够在手机和电脑上查看&#xff0c;还能在手机上进行交互操作&#xff0c;如放缩、旋转等&#xff0c;并且支持高清流畅的画面展示。以下是一些推荐的3D交互展示工具&#xff1a; 1、在线3D展示软件&…

牛客热题:寻找第K大

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;寻找第K大题目链接方法一&#…