树中两个结点的最低公共祖先

算法:树中两个结点的最低公共祖先 输入两个树结点,求它们的最低公共祖先。 如果是二叉树,并且是二叉搜索树,二叉树是排序过的,位于左子树的结点都比父节点要小,而位于右子树的结点都比父节点大,我们只需要从树的根结点开始和两个输入的结点进行比较。如果当前结点的值比两个结点的值都大,那么最低的共同父节点一定是在当前结点的左子树中,于是下一步遍历当前结点的左子树结点。反之则在右子树上。当找到一个结点在这两个结点的中间,那么就是最低的公共祖先。 如果该树不是二叉树,而且有指向父节点的指针。 如果树中的每个结点(除根结点之外)都有一个指向父节. 阅读详情
题目:
输入两个树节点,求它们的最低公共祖先。

分析:
这道题对于不同的树有不同的解法,分为以下几类:

1.二叉搜索树。
2.普通树,但结点中有指向父节点的指针。
3.普通数。
1.二叉搜索树

二叉搜索树中结点的左孩子值都小于结点的值,结点的右孩子值都大于结点的值。两个树结点的最低公共祖先肯定是将这两个树结点分隔到了不同的两个子树中,所以最低公共祖先的值肯定介于这两个树结点之间。从上往下遍历二叉搜索树,如果当前结点的值大于这两个树结点的值,就在当前结点的左子树中找,如果当前结点的值小于这两个树结点的值,就在当前结点结点的右子树中找,找到第一个值介于给定的两个树结点的值的结点就是这两个树结点的最低公共祖先。

参考代码:

struct TreeNode
{
    int value;
    TreeNode* left;
    TreeNode* right;
};

class Solution
{
public:
    TreeNode* getClosestCommonAncestor( TreeNode* node1, TreeNode* node2, TreeNode* root )
    {
        if ( node1 == NULL || node2 == NULL )
            return NULL;

        while ( root != NULL ) 
        {
            if ( root->value > node1->value && root->value > node2->value )
            {
                root = root->left;
            }
            else if ( root->value < node1->value && root->value < node2->value )
            {
                root = root->right;
            }
            else
            {
                return root;
            }
        }

        return root;
    }
};
2.普通树,但结点中有指向父结点的指针

如果树中有指向父结点的指针,就可以从给定的两个结点开始往回追溯,找到回溯路径中第一个公共结点。这个问题就可以转化为求两个链表的第一个公共结点。

参考代码:

struct TreeNode
{
    int value;
    TreeNode* left;
    TreeNode* right;
    TreeNode* parent;
};

class Solution
{
public:
    TreeNode* getClosestCommonAncestor2( TreeNode* node1, TreeNode* node2, TreeNode* root )
    {
        if ( node1 == NULL || node2 == NULL || root == NULL )
            return NULL;

        int node1Length = 0, node2Length = 0;
        int diffLength = 0;

        TreeNode* node1Temp = node1;
        TreeNode* node2Temp = node2;

        //分别计算两个结点到根结点的路径的长度
        while ( node1Temp != NULL )
        {
            node1Temp = node1Temp->parent;
            node1Length++;
        }
        while ( node2Temp != NULL )
        {
            node2Temp = node2Temp->parent;
            node2Length++;
        }

        node1Temp = node1;
        node2Temp = node2;

        //让路径较长的结点先走
        if ( node1Length >= node2Length )
        {
            diffLength = node1Length - node2length;
            while ( diffLength != 0 )
            {
                node1Temp = node1Temp->parent;
            }
        }
        else if ( node2Length < node2Length )
        {
            diffLength = node2Length - node1Length;
            while ( diffLength != 0 )
            {
                node2Temp = node2Temp->parent;
            }
        }

        //同步前进,找到第一个公共结点
        while ( node1Temp != NULL && node2Temp != NULL )
        {
            if ( node1Temp == node2Temp )
            {
                break;
            }
            else 
            {
                node1Temp = node1Temp->parent;
                node2Temp = node2Temp->parent;
            }
        }
        return node1Temp;
    }
};
3.普通树

利用辅助栈,在遍历树的时候找到根结点到两给定结点的路径,然后将其转化为两个链表求公共结点问题。

参考代码:

struct TreeNode
{
    int value;
    TreeNode *left;
    TreeNode *right;
};

class Solution
{
public:
    TreeNode* getClosestCommonAncestor3( TreeNode* node1, TreeNode* node2, TreeNode* root )
    {
        if ( node1 == NULL || node2 == NULL || root == NULL ) 
            return NULL;

        stack<TreeNode*> path1;
        stack<TreeNode*> path2;

        getNodePath( root, node1, path1 );
        getNodePath( root, node2, path2 );

        return getCommonNodeFromStack( path1, path2 );
    }

    TreeNode* getCommonNodeFromStack( 
            const stack<TreeNode*>& path1, 
            const stack<TreeNode*>& path2 )
    {
        int diffLength = 0;
        if ( path1.size() > path2.size() )
        {
            diffLength = path1.size() - path2.size();
            while ( diffLength != 0 )
            {
                path1.pop();
                diffLength--;
            }
        }
        else 
        {
            diffLength = path2.size() - path1.size();
            while ( diffLength != 0 )
            {
                path2.pop();
                diffLength--;
            }
        }

        while ( !path1.empty() && !path2.empty() )
        {
            if ( path1.top() == path2.top() )
            {
                break;
            }
            path1.pop();
            path2.pop();
        }
        return path1.top();
    }

    bool getNodePath( TreeNode* root, TreeNode* findNode, stack<TreeNode*>& path )
    {
        if ( root == NULL )
            return false;
        if (  root == findNode)
        {
            path.push( findNode );
            return true;
        }

        if ( getNodePath( root->left, findNode, path ) 
                || getNodePath( root->right, findNode, path ) )
        {
            path.push( root );
        }
    }
};
树中两结点的最低公共祖先(C++实现) 题目是,输入两个树结点,求它们的最低公共祖先 首先,要说明的是,这是一组题目,根据剑指Offer上所讲的,这道题可能会分好几种情况,因此,如果在面试时候遇到,我们需要和面试官沟通,而不是一上来就写代码。1. 如果给定树是二叉搜索树二叉搜索树(又叫二叉排序树),中序遍历是可以得到有序序列的,因此,我们可以利用这个性质来解题。假设给定的两个树结点为4,1,根据图示,显然3为最低公共祖先; 假设给定的两 阅读详情

相关推荐

树中两个结点的最低公共祖先(Java)

题目: 树中两个结点的最低公共祖先。 解决方法一: 假设是二叉搜索树(二叉搜索树是一个排序的二叉树,左子树的结点小于根结点,右子树的结点大于根结点),故找到一个结点,使其大于左子结点小于右子结点即可。 代码实现: public static TreeNode getLastCommonNode(TreeNode pRoot, TreeNode pLeft, TreeNode pRigh...

Sweet Baby,甜宝 3340

树中两个节点的最低公共祖先

一.树中两个节点的最低公共祖先 题目一:输入两个二叉搜索树的结点,求两个结点的最低公共祖先,所谓的最低公共祖先是指距离两个节点最近的共同祖先。 例如: 解题思路: 1.二叉搜索树具有一个很好的特点。以当前结点为根节点的左边结点的值都是小于根节点的值,右边结点的值都大于根节点的值。 2.根据这个特点,如果给的两个节点的值都小于根节点,那么它们的最低公共祖先就一定在它左子树。...

HanSion.Z 5284

九度OJ-题目1509:树中两个结点的最低公共祖先的测试数据

这是九度OJ-题目1509:树中两个结点的最低公共祖先的测试数据,input.txt是输入数据,output.txt是输出数据。

求树中两个节点的最低公共祖先

情形1:树是搜索二叉树 思路:从树的根节点开始遍历,如果根节点的值大于其中一个节点,小于另外一个节点,则根节点就是最低公共祖先。否则如果根节点的值小于两个节点的值,则递归求根节点的右子树,如果大于两个节点的值则递归求根的左子树。如果根节点正好是其中的一个节点,那么说明这两个节点在一条路径上,所以最低公共祖先则是根节点的父节点 public static BinaryTreeNode get

IT成长 3530

ROS机器人全覆盖路径规划实战:6种ipa算法对比与选型指南(附避坑经验)

本文深入对比了ROS中ipa_coverage_planning功能包集成的6种全覆盖路径规划算法,包括牛耕分解、栅格旅行商、神经网络、局部能量最小、轮廓线和凸感知放置。文章从覆盖率、重复率、计算效率、动态避障等核心工程指标出发,提供了基于不同场景(如静态/动态环境、规则/复杂布局)的实战选型指南,并分享了神经网络和局部能量最小等关键算法的参数调优与避坑经验,旨在帮助开发者根据实际需求选择并优化最合适的ipa覆盖算法。

perl8的博客 364

常学常新:《Attention Is All You Need》万字解读!

常学常新:《Attention Is All You Need》万字解读!

hunteritself的博客 3650

面试题68:树中两个节点的最低公共祖先

该题有三种变型: 一、如果该树是二叉查找树,求树中A,B两个节点的最低公共祖先,方法如下: 1.从树的根节点和两个输入节点开始进行比较,如果当前节点C的值比A,B节点值都大,那么最低的共同节点一定在当前节点的左子树中 2.如果当前节点C的值比A,B节点值都小,那么最低的共同父节点一定在当前节点的右子树中 3.在树中从上到下找到的第一个在两个输入节点值之间的节点就是最低的公共祖先 二...

R_g_Luo的博客 658

避坑指南:ShardingSphere连接达梦/金仓数据库时SQL解析器的那些‘坑‘

本文深入探讨了ShardingSphere与国产数据库(如达梦、金仓)集成时遇到的SQL解析器差异问题,提供了详细的解决方案和优化策略。通过分析SQL方言差异、JDBC实现差异及解析器兼容性,帮助开发者有效避坑,提升分布式数据库架构设计的效率与稳定性。

weixin_29309475的博客 392

九度OJ-题目1509:树中两个结点的最低公共祖先

题目链接地址: 九度OJ-题目1509:树中两个结点的最低公共祖先 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。 输入: 输入可能包含多个测试样例。 对于每个测试案例,输入的第一行为一个数n(0 其中每个测试样例包括两行,第一行为一个二叉树的先序遍历序列,其中左右子树若为空则用0代替,其中二叉树的结点个数node_num 第二行为树中的

蜗牛 1349

深水区探秘:小红书App x-s参数逆向与高并发爬虫实战(2026版)

在移动互联网的碎片化时代,小红书凭借其“社区+电商”的独特模式,积累了超过3亿月活用户。其内容生态覆盖了从美妆、穿搭到旅行、数码等几乎所有垂直领域。对于数据分析师、市场研究员以及AI算法工程师而言,小红书平台蕴含的价值是巨大的——无论是热门趋势洞察、KOL画像分析,还是多模态图文数据的采集。然而,想要高效、稳定地获取小红书App的公开数据,却并非易事。与Web端相比,小红书App的防护体系堪称“铜墙铁壁”。其核心的反爬机制建立在动态混淆的加密参数之上,尤其是请求头中的X-SX-T以及X-S-Common。

2201_76125261的博客 266

企业财务共享服务中心业务蓝图规划方案【附全文阅读】

《企业财务共享服务中心业务蓝图规划方案》为集团企业提供财务共享中心建设全流程指导,涵盖战略定位、组织架构、业务流程、信息系统、运营管理和变革实施六大维度。方案明确共享中心"交易处理+战略支撑"双重职能,设计专业分组架构,筛选标准化高、价值明确的流程(如核算、资金结算等)纳入共享范围,构建业财一体化平台,并配套绩效与风险管控体系。结合项目型企业管理特点,分阶段推进实施,助力企业实现财务集中化与标准化转型。

cdfunlove的博客 994

【面试题050】树中两个结点的最低公共祖先

【面试题050】树中两个结点的最低公共祖先 题目: 树中两个节点的最低公共祖先。 思路一: 输入两个树节点,求他们的最低公共祖先, ——如果是二叉树,而且是二叉搜索树,那么是可以找到公共节点的。 二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大。 如果当前节点的值比两个结点的值都大,那么...

A201241302241的博客 240

Qt/C++编写自定义控件42-开关按钮

一、前言 从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ、360卫士、金山毒霸等,都有很多开关控制一些操作,在Qt widgets应用项目上,在项目中应用些类似的开关按钮,估计也会为项目增添不少新鲜感。 总结了大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好...

Qt/C++视频监控/推流/物联网/大屏系统/自定义控件/UI定制/输入法 3328

剑指Offer学习总结-树中两个结点的最低公共祖先

剑指Offer学习总结-树中两个结点的最低公共祖先 本系列为剑指Offer学习总结,主要是代码案例的分析和实现: 书籍链接:http://product.dangdang.com/24242724.html 原作者博客:http://zhedahht.blog.163.com/blog/static/254111742011101624433132/ 原作者博客链接有完整的项目代码下载。

那远远的云端 708

如何配置SSC CANopen的excel文件

如何配置 CANOpen 的 EXCEL 文件

PI_sunyang的博客 3703

Vue3 - 超详细最新 wangEditor V5 富文本编辑器安装引入及使用教程,提供工具栏配置、基础富文本功能、API使用示例教程等(新手小白快速引入并植入到项目中)

vue3,wangEditorv5富文本编辑器,wangEditorv5官方文档,vue3最新安装wangEditorv5富文本详细使用教程,vue3使用wangEditorv5编辑器示例代码,vue3网站网页安装植入富文本编辑器教程,vue3wangEditor使用api,vue3安装富文本控制台出现报错如何解决,vue3wangEditor-v5工具栏配置,vue3中使用富文本编译器wangEditor5的方法,wangeditor5在vue3中的全使用过程,vue3超详细最新wangedi

🏆 前端领域优质创作者 4253

寻找树中两个结点的最低公共祖先

寻找树中两个结点的最低公共祖先 Q:在树中寻找两个结点的最低公共祖先,是什么意思呢? A:树是由根节点衍生左右孩子继续衍生左右孩子的左右孩子。所以呢树中的两个结点是一定拥有最低公共祖先(这两个结点Q:是在这个祖先结点衍生的孩子中)至于最低:就是第一个公共祖先。 树是二叉树并且是BST树嘛? 我们根据BST树(二叉搜索树/二叉排序树)的特性:树中任意结点的val大于左孩子的val。 如果该结点是这两个结点的最低公共祖先 那么他的val一定是大于等于其中一个结点的val,并且小于另外一个结点的val 或者

LuKeYY825的博客 451

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

树中两个结点的最低公共祖先-C++

// 面试题68:树中两个结点的最低公共祖先 // 题目:输入两个树结点,求它们的最低公共祖先。 #include #include #include using namespace std; struct TreeNode { int m_nValue; std::vector m_vChildren; }; TreeNode *CreateTreeNode(int value) { TreeNode

了解➔熟悉➔掌握➔精通 1043

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

[剑指offer]树中两个结点的最低公共祖先

树中两个结点的最低公共祖先 题目 给出一个二叉树,输入两个树节点,求它们的最低公共祖先。 一个树节点的祖先节点包括它本身。 注意 输入的二叉树不为空; 输入的两个节点一定不为空,且是二叉树中的节点; 样例 二叉树 [8, 12, 2, null, null, 6, 4, null, null, null, null] 如下图所示:      8 &nb...

weixin_44922845的博客 290

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

树中两个结点的最低公共祖先 ----《剑指offer》面试题50

题目 求树中两个结点的最低公共祖先,此树不是二叉树,并且没有指向父节点的指针。 思路 一: 如果是二叉搜索树  位于左子树的结点都比父结点小,而位于右子树的结点都比父结点大。那么在树中从上到下找到的第一个在两个输入结点的值之间的结点,就是最低的公共祖先。   二: 如果不是二叉搜索树,但是每个结点有指向父结点的指针  组织两条链表,每个链表是由叶结点指向根结点的路径。从而将问题转换成:求两个...

baboon_chen 608
上一篇: 把字符串转换为整数
下一篇: 数组中重复的数字
Findway_
博客等级 码龄10年 36粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值