zoukankan      html  css  js  c++  java
  • LeetCode236. 二叉树的最近公共祖先

    * @lc app=leetcode.cn id=236 lang=cpp
     *
     * [236] 二叉树的最近公共祖先
     *
     * https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
     *
     * algorithms
     * Medium (58.46%)
     * Likes:    300
     * Dislikes: 0
     * Total Accepted:    33.9K
     * Total Submissions: 57.9K
     * Testcase Example:  '[3,5,1,6,2,0,8,null,null,7,4] 5 1'
     *
     * 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
     * 
     * 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x
     * 的深度尽可能大(一个节点也可以是它自己的祖先)。”
     * 
     * 例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]
     * 
     * 
     * 
     * 
     * 
     * 示例 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。因为根据定义最近公共祖先节点可以为节点本身。
     *
     
     * 说明:
     * 
     * 
     * 所有节点的值都是唯一的。
     * p、q 为不同节点且均存在于给定的二叉树中。
     * 
     * 
     
    思路:分别找到到两个节点的路径,然后分别遍历两个路径 找到最后一个共同的结点,即为他们的共同祖先
     
    class Solution {
    private:
    ///深度搜索找到到两个目标节点的路径,
        bool find(TreeNode* root,TreeNode*p,vector<TreeNode*>&vec)
        {
            if(root==NULL) return false;
            vec.emplace_back(root);
            if(root->val==p->val) return true;
            if(find(root->left,p,vec)) return true;
            if(find(root->right,p,vec)) return true;
            vec.pop_back();
            return false; 
        }
    public:
        vector<TreeNode*> vecp;
        vector<TreeNode*> vecq;
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            find(root,q,vecq);
            find(root,p,vecp);
            int i=1;
            for(i=1;i<vecq.size()&&i<vecp.size();++i)
            {
                if(vecp[i]!=vecq[i]) 
                    return vecp[i-1];
    
            }
        return vecp[i-1];
        }
    };

    思路2
    两个节点p,q分为两种情况:

    p和q在相同子树中
    p和q在不同子树中
    从根节点遍历,递归向左右子树查询节点信息
    递归终止条件:如果当前节点为空或等于p或q,则返回当前节点

    递归遍历左右子树,如果左右子树查到节点都不为空,则表明p和q分别在左右子树中,因此,当前节点即为最近公共祖先;
    如果左右子树其中一个不为空,则返回非空节点。

    class Solution{
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            if(root==NULL || root==p || root==q) return root;
            TreeNode* left=lowestCommonAncestor(root->left,p,q);
            TreeNode* right=lowestCommonAncestor(root->right,p,q);
            if(left&&right) return root;
            return left?left:right;
        }
    };
  • 相关阅读:
    docker安装
    快速删除docker中的容器
    CentOS赋予一个普通用户root权限
    大型电商网站:第三章:环境搭建
    面试:第十一章:缓存
    面试:第十章:单点登录
    面试:第九章:分布式 、高并发、集群、负载均衡、高可用
    面试:第八章:SpringMVC、Springboot、Mybatis、Dubbo、Zookeeper、Redis、Elasticsearch、Nginx 、Fastdfs、ActiveMQ
    面试:第七章:冷门面试题
    大型电商网站:第一章:主要电商模式
  • 原文地址:https://www.cnblogs.com/renzmin/p/11994413.html
Copyright © 2011-2022 走看看