栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

在二叉树中找到两个节点的最近公共祖先(C++)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在二叉树中找到两个节点的最近公共祖先(C++)

在二叉树中找到两个节点的最近公共祖先 描述

  给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足1≤n≤105 , 节点值val满足区间 [0,n)

要求:时间复杂度 O(n)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

  所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。

注意:节点本身可以视为自己的祖先。

示例1
输入:
{3,5,1,6,2,0,8,#,#,7,4},5,1
返回值:
3
示例2
输入:
{3,5,1,6,2,0,8,#,#,7,4},2,7
返回值:
2
思路/解法 方式一

使用深度遍历(仅仅只是一开始默认向左子树深度搜索,然后到底部之后转向右子树,直至左右子树均搜索之后强制返回到上一节点),当找到o1或者o2时,分别记录其当前节点的所有父类,最后比较两个数据,得到最近的公共父节点。


class Solution {
public:
    
    
    int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
        vector arro1;
        vector arro2;
        vector arr;
        stack stacks;
        bool left = false;
        bool right = false;
        while(root || !stacks.empty())
        {
            while(root)
            {
                stacks.push(root);
                arr.push_back(root->val);
                if(root->val == o1 && left == false)
                {
                    arro1.assign(arr.begin(),arr.end());
                    left = true;
                }
                if(root->val == o2 && right == false)
                {
                    arro2.assign(arr.begin(),arr.end());
                    right = true;
                }
                root = root->left?root->left:root->right;
            }
            
            root = stacks.top();
            stacks.pop();
            arr.pop_back();
            if(!stacks.empty() && stacks.top()->left == root)
                root = stacks.top()->right;
            else
                root = nullptr;
        }
        int res = 0;
        if(arro1.size()>=arro2.size())
        {
            for(int i =arro2.size()-1;i>=0;i--)
            {
                auto iter = find(arro1.begin(),arro1.end(),arro2[i]);
                if(iter!=arro1.end())
                {
                    res = arro2[i];
                    break;
                }
            }
        }
        else
        {
            for(int i =arro1.size()-1;i>=0;i--)
            {
                auto iter = find(arro2.begin(),arro2.end(),arro1[i]);
                if(iter!=arro2.end())
                {
                    res = arro1[i];
                    break;
                }
            }
        }
        return res;
    }
};
方式二

通过递归方式进行查询查找,但是时间复杂度过高,运行会超时,仅供参考。


class Solution {
public:
    
    
    bool GetDepth(TreeNode* node,int o1,int o2)
    {
        if(node == nullptr)return false;
        if(node->val == o1 || node->val == o2)
            return true;
        return GetDepth(node->left, o1, o2) || GetDepth(node->right, o1, o2);
    }
    
    int FatherNode(TreeNode* node,int o1,int o2)
    {
        if(node == nullptr)return 0;
        //以下情况为有一个带查找节点为父节点
        if(node->val == o1 && (GetDepth(node->left, o1, o2) || GetDepth(node->right, o1, o2)))
            return o1;
        
        if(node->val == o2 && (GetDepth(node->left, o1, o2) || GetDepth(node->right, o1, o2)))
            return o2;
        
        //左子树没找到,则全在右子树上
        if(!GetDepth(node->left, o1, o2))
            return FatherNode(node->right,o1,o2);
        //右子树没找到,则全在左子树上
        if(!GetDepth(node->right, o1, o2))
            return FatherNode(node->left,o1,o2);
        return node->val;
    }

    
    int lowestCommonAncestor(TreeNode* root, int o1, int o2) 
    {
        return FatherNode(root,o1,o2);
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/853630.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号