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

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

百度百科中最近公共祖先的定义为:“对于有根树 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 map = new HashMap();
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //借助hash表存储每个节点的父节点,然后向上遍历是够存在共同节点
        
        if(root == null || root == p || root == q) return root;

        //dfs遍历,为每个节点添加父节点
        dfs(root);

        //set集合特点:无序、不重复
        Set set = new HashSet();

        //将节点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-二叉树的最近公共祖先)