LeetCode 算法:二叉树的最近公共祖先 III c++

原题链接🔗:二叉树的最近公共祖先
难度:中等⭐️⭐️

题目

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

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

二叉树最近公共祖先

在二叉树中找到两个节点的最近公共祖先(Lowest Common Ancestor,
LCA)是一个常见的算法问题。最近公共祖先是指在二叉树中,能够同时包含两个给定节点的最低(即最深的)节点。以下是解决这个问题的一般步骤和考虑因素:

  • 理解问题:你需要找到两个给定节点在二叉树中的LCA。

  • 递归方法:递归是解决这个问题的常用方法。你可以从根节点开始,递归地搜索两个节点。

  • 基本情况

    • 如果当前节点为空,返回空。
    • 如果当前节点等于其中一个给定节点,返回当前节点。
  • 递归搜索

    • 在当前节点的左子树和右子树中递归地搜索两个节点。
  • 合并结果

    • 如果在左子树中找到了一个节点,在右子树中也找到了另一个节点,那么当前节点就是LCA。
    • 如果只在左子树或右子树中找到了一个节点,那么LCA就是这个子树中的节点。
    • 如果两个子树都为空,那么当前节点不是LCA的一部分。
  • 实现:使用递归函数实现上述逻辑。

  • 测试:确保你的解决方案可以处理各种情况,包括但不限于:

    • 二叉树只有一个节点。
    • 两个节点在不同的分支上。
    • 两个节点在相同的分支上。
    • 两个节点中的一个或两个都是根节点。
  • 优化:考虑算法的时间复杂度和空间复杂度。递归方法的时间复杂度通常是O(N),其中N是树中节点的数量,空间复杂度取决于树的高度,最坏情况下是O(N)。

题解

  1. 解题思路

LeetCode 上的 “二叉树的最近公共祖先 III” 题目要求解决的是在二叉树中找到两个节点的最近公共祖先(LCA)。这个问题可以通过递归的方式来解决,下面是解题的一般思路:

  • 定义问题:给定两个值,找到二叉树中包含这两个值的最近公共祖先。

  • 理解二叉树:二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点。

  • 递归方法

    • 递归函数将接收当前节点和两个值作为参数。
    • 如果当前节点为空,返回空。
    • 检查当前节点是否等于两个值中的任意一个,如果是,返回当前节点。
    • 递归地在左子树和右子树中查找这两个值。
  • 处理递归结果

    • 如果左子树和右子树都为空,说明当前节点的子树中没有找到两个值,返回空。
    • 如果左子树和右子树都非空,说明两个值分别在左右子树中,当前节点就是它们的LCA,返回当前节点。
    • 如果只有一个子树非空,说明两个值都在一个子树中,继续在该子树中查找LCA
  1. c++ demo
#include <iostream>
#include <vector>


struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 如果当前节点为空或者等于p或q,返回当前节点
        if (!root || root == p || root == q) {
            return root;
        }

        // 递归地在左子树和右子树中查找p和q
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);

        // 如果左右子树都为空,说明p和q都不在当前节点的子树中
        if (!left && !right) {
            return nullptr;
        }

        // 如果左右子树中只有一个为空,说明p和q都在非空的子树中
        if (left && !right) {
            return left;
        }
        if (!left && right) {
            return right;
        }

        // 如果左右子树都不为空,说明p在一边,q在另一边,当前节点是它们的LCA
        return root;
    }
};

int main() {
    // 构建示例二叉树
    //       2
    //      / \
    //     3   5
    //    / \   \
    //   1   4   6
    TreeNode* root = new TreeNode(2);
    root->left = new TreeNode(3);
    root->right = new TreeNode(5);
    root->left->left = new TreeNode(1);
    root->left->right = new TreeNode(4);
    root->right->right = new TreeNode(6);

    // 创建两个节点
    TreeNode* p = root->left->left; // 值为1的节点
    TreeNode* q = root->right->right; // 值为6的节点

    // 创建Solution对象并调用函数
    Solution solution;
    TreeNode* lca = solution.lowestCommonAncestor(root, p, q);

    // 打印结果
    if (lca) {
        std::cout << "LCA of " << p->val << " and " << q->val << " is " << lca->val << std::endl;
    }
    else {
        std::cout << "No common ancestor found." << std::endl;
    }

    // 清理内存
    delete root->left->left;
    delete root->left->right;
    delete root->right->right;
    delete root->left;
    delete root->right;
    delete root;

    return 0;
}
  • 输出结果:

LCA of 1 and 6 is 2

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

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

相关文章

Jackson与Json、Json和各种Java数据类型的互相转化

jackson是什么 json是最常用的数据交换格式 Jackson是最流行的Json库 首先对于这种JSON序列化的库其实有非常多&#xff0c;比如我们熟悉的Gson&#xff0c;Fastjson等等&#xff0c;当然技术没有完全的好坏&#xff0c;但是从使用情况和社区生态等方面综合看来&#xff0c;Ja…

uni-app x 跨平台开发框架

目录 uni-app x 是什么 和Flutter对比 uts语言 uvue渲染引擎 组合式API的写法 选项式API写法 页面生命周期 API pages.json全局配置文件 总结 uni-app x 是什么 uni-app x&#xff0c;是下一代 uni-app&#xff0c;是一个跨平台应用开发引擎。 uni-app x 是一个庞…

A4-C四驱高防轮式巡检机器人

在当今数字化和智能化迅速发展的时代&#xff0c;旗晟智能带来了一款革命性的创新产品——A4-C四驱高防轮式巡检机器人。这款机器人以其卓越的性能和多功能性&#xff0c;为工业巡检领域带来了全新的解决方案。 一、产品亮点 1、四驱动力与高防护设计 四驱高防轮式巡检机器人…

el-table封装点击列筛选行数据功能,支持筛选,搜索,排序功能

数据少的话&#xff0c;可以前端实现&#xff0c;如果多的话&#xff0c;建议还是请求接口比较合理父组件&#xff1a; <template> <div class"home"> <!-- <img alt"Vue logo" src"../assets/logo.png"> <HelloWorld …

重塑通信边界,基于ZYNQ7000 FPGA驱动的多频段多协议软件无线电平台

01、产品概述 本平台是基于高性能ZYNQ-7000系列中的XC7Z045处理器构建的多频段多协议软件无线电解决方案&#xff0c;集成了AD9364芯片——一款业界领先的1x1通道RF敏捷收发器&#xff0c;为无线通信应用提供了强大支持。其存储架构包括2路高速4GB DDR3内存、1路32GB EMMC存储以…

springboot dynamic配置多数据源

pom.xml引入jar包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version> </dependency> application配置文件配置如下 需要主要必须配置…

ASUS/华硕飞行堡垒8 FX506L FX706L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;Windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…

【收藏级神丹】Liae384_刘亦菲_直播可用,平衡度最高的原创神丹,独家珍稀资源

Liae384_刘亦菲_DFL神丹&#xff1a;点击下载 此丹较重&#xff0c;小卡可以使用但不能训练&#xff0c;实测复训适合24G卡8G、12G、16G卡下载练好的专丹直接使用即可384的Liae对各类杂论视频兼容比较好&#xff0c;高参也能容忍高分辨率的DST复用方式: 非必要不用删除AB&…

Docker:二、常用命令

&#x1f341;docker常用命令 官方帮助文档&#xff1a;https://docs.docker.com/reference/ &#x1f332;帮助命令&#xff08;版本信息&#xff09; docker -v # 显示docker版本 docker version # 显示docker版本信息 docker info # 显示docker系统信息 docker 命…

人工智能系列-numpy(三)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 副本和视图 副本 副本是一个数据的完整的拷贝&#xff0c;如果我们对副本进行修改&#xff0c;它不会影响到原始数据&#xff0c;物理内存不再同一位置。副本一般发生在Pytho…

Java--继承

1.继承的本质是对某一批类的抽象&#xff0c;从而实现对世界更好的建模 2.extends的意思是“扩展”&#xff0c;子类是父亲的扩展 3.Java中只有单继承&#xff0c;没有多继承 4.继承关系的两个类&#xff0c;一个为子类&#xff08;派生类&#xff09;&#xff0c;一个为父类…

零基础学python(一)

1. 匿名函数 常规函数&#xff1a; def fun(x, y):return x y 匿名函数&#xff1a; # lambda 空格后面是函数入参&#xff0c;冒号后面写函数体/函数逻辑 a lambda x,y: x y print(a(2,3)) 匿名函数/lambda函数的最大优点就是快速定义函数&#xff0c;使代码更精简。 …

第一百四十五节 Java数据类型教程 - Java字符串类型

Java数据类型教程 - Java字符串类型 零个或多个字符的序列称为字符串。 在Java程序中&#xff0c;字符串由java.lang.String类的对象表示。 String类是不可变的。 String对象的内容在创建后无法修改。 String类有两个伴随类&#xff0c;java.lang.StringBuilder和java.lang.…

欧科云链大咖对话:Web3原生创新静默期,科技巨头却在两极化发展

出品&#xff5c;OKG Research 作者&#xff5c;Hedy Bi 上周末&#xff0c;欧科云链研究院接受FT中文的邀请&#xff0c;作为圆桌嘉宾参与了由FT中文网与上海交通大学上海高级金融学院联合主办的金融大师课。在圆桌环节&#xff0c;笔者与各位教授和金融行业科技创新前沿实践…

基于aardio web.view2库和python playwright包的内嵌浏览器自动化操作

通过cdp协议可以实现playwright操控webview。 新建Python窗口工程 修改pip.aardio 修改pip.aardio&#xff0c;并执行&#xff0c;安装playwright。 //安装模块 import process.python.pip; //process.python.path "python.exe";/* 安装模块。 参数可以用一个字…

工地/矿区/电力/工厂/环卫视频智能安全监控反光衣AI检测算法的原理及场景应用

一、引言 随着科技的快速发展&#xff0c;特别是在智能交通和安全生产领域&#xff0c;对于夜间或弱光环境下的人员识别和安全监控需求日益凸显。反光衣作为一种重要的安全装备&#xff0c;被广泛应用于道路施工、工地作业、夜间巡逻、安全生产等场景&#xff0c;旨在提高人员的…

Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题

目录 Vue优化路径 一、使用key 二、使用冻结对象 三、使用函数式组件 四、使用计算属性 五、使用非实时绑定的表单项 六、保持对象引用稳定 6.1、保持对象引用稳定定义 6.2、保持对象引用稳定与不稳定的例子 6.3、vue2判断数据是否变化是通过hasChanged函数实现的 ①…

Spring AOP、Spring MVC工作原理、发展演变、常用注解

Spring AOP 概念 AOP全称为Aspect Oriented Programming&#xff0c;表示面向切面编程。切面指的是将那些与业务无关&#xff0c;但业务模块都需要使用的功能封装起来的技术。 AOP基本术语 **连接点&#xff08;Joinpoint&#xff09;&#xff1a;**连接点就是被拦截到的程序执…

智能文档革新:合合信息智能文档处理平台上线基金合同抽取模型!

一、什么是基金合同&#xff1f; 基金合同是指具有平等地位主体的基金当事人在基金活动中&#xff0c;为规范其间的权利、义务&#xff0c;依意思表示一致而形成的契约或协议。《证券投资基金法》第五十二条规定&#xff0c;公开募集基金的基金合同应当包括下列内容: &#x…

软件游戏d3dcompiler_43.dll丢失怎么办,总结几种有效的方法

在使用电脑时&#xff0c;可能会碰到找不到d3dcompiler_43.dll的问题。即在使用过程中&#xff0c;突然弹出一个提示“d3dcompiler_43.dll丢失”&#xff0c;由于此文件的缺失&#xff0c;部分程序将无法启动。为恢复正常使用&#xff0c;我们需要修复此文件。接下来&#xff0…