美文网首页
Leetcode-二叉树的最近公共祖先

Leetcode-二叉树的最近公共祖先

作者: 风暴小狼 | 来源:发表于2020-05-11 15:43 被阅读0次

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

    百度百科中最近公共祖先的定义为:“对于有根树 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。因为根据定义最近公共祖先节点可以为节点本身。

    解题思路:

    1. 借助外部存储

    使用hash表记录每个节点的父节点,遍历p和q的父节点,第一个共同的节点即为最近公共祖先。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        
        private Map<Integer,TreeNode> map = new HashMap<Integer,TreeNode>();
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            //借助hash表存储每个节点的父节点,然后向上遍历是够存在共同节点
            
            if(root == null || root == p || root == q) return root;
    
            //dfs遍历,为每个节点添加父节点
            dfs(root);
    
            //set集合特点:无序、不重复
            Set<TreeNode> set = new HashSet<TreeNode>();
    
            //将节点p或者q的父节点存入set集合
            while(p != null)
            {
                set.add(p);
                p = map.get(p.val);
            }
            
           //查看q的父节点是否存在集合中
            while(q != null)
            {
                if(set.contains(q))
                {
                    return q;
                }
                q = map.get(q.val);
            }
            
            return null;
        }
        
        private void dfs(TreeNode root)
        {
            if(root.left != null)
            {
                map.put(root.left.val,root);
                dfs(root.left);
            }
            
            if(root.right != null)
            {
                map.put(root.right.val,root);
                dfs(root.right);
            }
        }
    }
    
    2.深度优先搜索

    对二叉树进行后序遍历,查找p和q节点,向上回溯找到公共祖先。
    递归解析:

    明确边界:
    1.当越过叶子节点时,直接返回null
    2.当节点root==p 或者q时,返回root

    递归内容:
    分别递归二叉树的左右子节点,返回值标记为left和right

    返回值:
    当left和right均不为空时,返回root节点
    当left和right均为空时,返回null
    当left不为空,则返回left
    当right不为空,返回right

    实现:

    class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            
            //dfs
    
            if(root == null) return null;
    
            if(root == p || root == q) return root;
    
            TreeNode left = lowestCommonAncestor(root.left,p,q);
            TreeNode right = lowestCommonAncestor(root.right,p,q);
    
            if(left != null && right != null) return root;
    
            if(left == null) return right;
            if(right == null) return left;
    
            return null;
        }
    }
    

    相关文章

      网友评论

          本文标题:Leetcode-二叉树的最近公共祖先

          本文链接:https://www.haomeiwen.com/subject/uldunhtx.html