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

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

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

    code1:

    左右子树的近公共结点可以是左右子树其中任何一结点,也可是其最近公共根节点
    应该采用后序遍历,因为只有找到p、q后,才可以找其最近公共祖先结点,而在二叉排序树中找其最近公共祖先结点时,因为已经有结点的大小关系,所以可以用先序遍历根据结点的大小关系来判断

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            if(!root||!p||!q)
                return nullptr;
            
            TreeNode* resNode=nullptr;
            lowestCommonAncestorCore(root,p,q,resNode);
            return resNode;
        }
    private:
        int lowestCommonAncestorCore(TreeNode* curNode,TreeNode* p,TreeNode* q,TreeNode* &resNode)
        {
            if(!curNode)
                return 0;
        
            int left=lowestCommonAncestorCore(curNode->left,p,q,resNode);
            int right=lowestCommonAncestorCore(curNode->right,p,q,resNode);
            int cur=(curNode==p||curNode==q)?1:0;
            if(left+right+cur>=2)
                resNode=curNode;
            return left||right||cur?1:0;
        }
    };

     code2:非递归;

    1. 首先把从root到p和q的路径都加入到parent中
    2. 然后在ancestor中存储p到根结点的路径
    3. 从q到根结点向上找,直到找到一个结点在ancestor中,该结点就是p、q的第一个最近公共祖先
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            if(!root||!p||!q)
                return nullptr;
            
            unordered_map<TreeNode*,TreeNode*> parent;
            deque<TreeNode*> stack;
            parent[root]=nullptr;
            stack.push_back(root);
    
            while(!stack.empty()&&(find(stack.begin(),stack.end(),p)==stack.end()||find(stack.begin(),stack.end(),q)==stack.end()))
            {
                TreeNode* node=stack.back();
                stack.pop_back();
                if(node&&node->left)
                {
                    stack.push_back(node->left);
                    parent[node->left]=node;
                }
                if(node&&node->right)
                {
                    stack.push_back(node->right);
                    parent[node->right]=node;
                }
            }
    
            unordered_set<TreeNode*> ancerstor;
            while(p)
            {
                ancerstor.insert(p);
                p=parent[p];
            }
            while(ancerstor.find(q)==ancerstor.end())
                q=parent[q];
    
            return q;
        }
    };
  • 相关阅读:
    Java实现 LeetCode 802 找到最终的安全状态 (DFS)
    Java实现 LeetCode 802 找到最终的安全状态 (DFS)
    Java实现 LeetCode 802 找到最终的安全状态 (DFS)
    Java实现 LeetCode 804 唯一摩尔斯密码词 (暴力)
    Java实现 LeetCode 803 打砖块 (DFS)
    Java实现 LeetCode 804 唯一摩尔斯密码词 (暴力)
    Java实现 LeetCode 803 打砖块 (DFS)
    Java实现 LeetCode 804 唯一摩尔斯密码词 (暴力)
    英文标点
    post sharp 与log4net 结合使用,含执行源码 转拷
  • 原文地址:https://www.cnblogs.com/tianzeng/p/11975407.html
Copyright © 2011-2022 走看看