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

news2024/12/26 0:07:29

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

题目

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

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

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

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

相关文章

Streaming local LLM with FastAPI, Llama.cpp and Langchain

题意&#xff1a; 使用FastAPI、Llama.cpp和Langchain流式传输本地大型语言模型 问题背景&#xff1a; I have setup FastAPI with Llama.cpp and Langchain. Now I want to enable streaming in the FastAPI responses. Streaming works with Llama.cpp in my terminal, but…

Android车载开发中调试app与bat结合的丝滑小妙招

项目场景&#xff1a; 做Android车载的小伙伴调试app的时候常年就是手动adb命令三连&#xff0c;例如我常用的adb推送apk的命令 adb root adb remount adb push D:\workspace_atc\XSP3-10A\AutoSystemUIPlugin\app\release\CarSystemUI.apk /system/priv-app/CarSystemUI …

【Linux进程】进程优先级 Linux 2.6内核进程的调度

前言 进程是资源分配的基本单位, 在OS中存在这很多的进程, 那么就必然存在着资源竞争的问题, 操作系统是如何进行资源分配的? 对于多个进程同时运行, 操作系统又是如何调度达到并发呢? 本文将以Linux kernel 2.6为例 , 向大家介绍进程在操作系统中 (OS) 的调度原理; 1. 进程优…

什么是网络抓取|常见用例和问题

你可能听说过数据被称为现代信息社会的新石油。由于线上信息量庞大&#xff0c;能够有效地收集和分析网页数据已经成为企业、研究人员和开发人员的关键技能。这就是网页抓取技术的用武之地。网页抓取&#xff0c;也称为网页数据提取&#xff0c;是一种强大的技术&#xff0c;能…

国际上备考所有AWS云计算/IT证书的五大优质免费课程网站

最近越来越多的小伙伴来问小李哥&#xff0c;小李哥亚马逊云科技AWS认证大满贯是在哪里上课复习的呢&#xff1f;全部上付费课程那不是一笔巨款吗&#xff1f;小李哥这次来盘点备考国际上IT证书的5大优质免费课程网站(不只是亚马逊云科技AWS的课程&#xff0c;其他课程同样可以…

46.修复HOOK对代码造成的破坏

上一个内容&#xff1a;45.使用hook点链表实现指定跳转 以 45.使用hook点链表实现指定跳转 它的代码为基础进行修改 此代码已实现无敌与秒杀功能 HOOKPOINT.h文件里的修改 #pragma oncetypedef struct CPUINFO {unsigned eflags;unsigned edi;unsigned esi;unsigned ebp;un…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十)-git(2)

下面是一些git的常用命令和基本操作&#xff0c;可以当做平常的笔记查询&#xff0c;用于学习&#xff01;&#xff01;&#xff01; 文章目录 前言 一、git 二、git常用命令 总结 前言 下面是一些git的常用命令和基本操作&#xff0c;可以当做平常的笔记查询&#xff0c;用于…

【python】Python中常用的数据结构——列表、元组和字典

python中的数据结构 列表、元组、字典的区别元组&#xff0c;字典&#xff0c;列表三者之间如何实现嵌套生成一个单一元素的元组、列表列表的地址列表、元组和字典的增删改查 列表、元组、字典的区别 列表、元组和字典是Python中常用的数据结构&#xff0c;它们各自有不同的特…

Infinitar链游新发展新机遇

区块链游戏市场在近年来经历了显著增长&#xff0c;吸引了大量的投资和关注。随着加密货币和NFT&#xff08;非同质化代币&#xff09;概念的普及&#xff0c;越来越多的投资者、游戏开发者和看到了区块链技术在游戏领域的应用潜力&#xff0c;纷纷涌入市场。区块链游戏的用户量…

昇思25天学习打卡营第07天 | 函数式自动微分

昇思25天学习打卡营第07天 | 函数式自动微分 文章目录 昇思25天学习打卡营第07天 | 函数式自动微分函数与计算图微分函数与梯度Stop GradientAuxiliary data 神经网络梯度计算总结打卡 神经网络的训练主要使用反向传播算法&#xff0c;首先计算模型预测值&#xff08;logits&am…

Prompt-Free Diffusion: Taking “Text” out of Text-to-Image Diffusion Models

CVPR2024 SHI Labshttps://arxiv.org/pdf/2305.16223https://github.com/SHI-Labs/Prompt-Free-Diffusion 问题引入 在SD模型的基础之上&#xff0c;去掉text prompt&#xff0c;使用reference image作为生成图片语义的指导&#xff0c;optional structure image作为生成图片…

【Leetcode笔记】406.根据身高重建队列

文章目录 1. 题目要求2.解题思路 注意3.ACM模式代码 1. 题目要求 2.解题思路 首先&#xff0c;按照每个人的身高属性&#xff08;即people[i][0]&#xff09;来排队&#xff0c;顺序是从大到小降序排列&#xff0c;如果遇到同身高的&#xff0c;按照另一个属性&#xff08;即p…

关于SAP SAP NetWeaver AS JAVA 授权问题漏洞(CVE-2020-6287)及修复

路径参考 SAP NetWeaver AS Java 严重漏洞 (CVE-2020-6287) 安全通告 - 威胁通告 - 绿盟科技-巨人背后的专家 SAP NOTE ​​​​​​https://me.sap.com/notes/2939665 找到路径 导航到 http(s)://<主机名>:port/nwa -> 配置 -> 基础架构 -> Java HTTP 提供…

Leetcode - 周赛403

目录 一&#xff0c;3200. 三角形的最大高度 二&#xff0c;3195. 包含所有 1 的最小矩形面积 I 三&#xff0c;3196. 最大化子数组的总成本 四&#xff0c;3197. 包含所有 1 的最小矩形面积 II 一&#xff0c;3200. 三角形的最大高度 本题是一道模拟题&#xff0c;可以先排…

从零开始手写STL库:Vector

从零开始手写STL库–Vector部分 文章目录 从零开始手写STL库--Vector部分Vector是什么Vector需要包含什么函数1&#xff09;基础成员函数2&#xff09;核心功能 基础成员函数的编写核心功能函数的编写总结 Vector是什么 std::vector 是一个动态数组&#xff0c;它在内存中以连…

安装Nginx以及简单使用 —— windows系统

一、背景 Nginx是一个很强大的高性能Web和反向代理服务&#xff0c;也是一种轻量级的Web服务器&#xff0c;可以作为独立的服务器部署网站&#xff0c;应用非常广泛&#xff0c;特别是现在前后端分离的情况下。而在开发过程中&#xff0c;我们常常需要在window系统下使用Nginx作…

SwiftUI中List的liststyle样式及使用详解添加、移动、删除、自定义滑动

SwiftUI中的List可是个好东西&#xff0c;它用于显示可滚动列表的视图容器&#xff0c;类似于UITableView。在List中可以显示静态或动态的数据&#xff0c;并支持垂直滚动。List是一个数据驱动的视图&#xff0c;当数据发生变化时&#xff0c;列表会自动更新。针对List&#xf…

关于下载obsidian SimpRead Sync中报错的问题

参考Kenshin的配置方法&#xff0c;我却在输入简悦的配置文件目录时多次报错。 bug如下&#xff1a; 我发现导出来的配置文件格式如下&#xff1a; 然后根据报错的bug对此文件名进行修改&#xff0c;如下&#xff1a; 解决。

【后端面试题】【中间件】【NoSQL】MongoDB查询优化2(优化排序、mongos优化)

优化排序 在MongoDB里面&#xff0c;如果能够利用索引来排序的话&#xff0c;直接按照索引顺序加载数据就可以了。如果不能利用索引来排序的话&#xff0c;就必须在加载了数据之后&#xff0c;再次进行排序&#xff0c;也就是进行内存排序。 可想而知&#xff0c;如果内存排序…

elasticsearch-users和elasticsearch-reset-password介绍

elasticsearch 内置 elastic, kibana, logstash_system,beats_system 共4个用户&#xff0c;用途如下&#xff1a; elastic 账号&#xff1a;内置的超级用户&#xff0c;拥有 superuser 角色。 kibana 账号&#xff1a;用来连接 elasticsearch 并与之通信。Kibana 服务器以该用…