236. Lowest Common Ancestor of a Binary Tree

一、题目

  1、审题

  

  2、分析

    求二叉树中 p、q 节点的最小共同祖先节点。

 

二、解答

  1、思路

    方法一、

      采用循环查找。

      ①、若 root 为 p 或者 q ,则返回 root

      ②、若 p、q 分布在 root 不同的左右子树,则返回 root

      ③、若 p、q 均为 root 左子树,则 root = root.left; 若 p、q均在右子树,则 root = root.right。

 1     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
 2         while(root != null) {
 3             if(root.val == p.val || root.val == q.val)
 4                 return root;
 5             
 6             boolean pInLeft = isChildren(root.left, p);
 7             boolean qInRight = isChildren(root.right, q);
 8 
 9             if((pInLeft && qInRight) || (!pInLeft && !qInRight))
10                 return root;
11             
12             if(pInLeft)    // p、q 均在 left
13                 root = root.left;
14             else     // p、q 均在 right
15                 root = root.right;
16         }
17         return null;
18     }
19     
20     private boolean isChildren(TreeNode root, TreeNode p) {
21         TreeNode node = root;
22         while(node != null) {
23             if(node.val == p.val)
24                 return true;
25             else 
26                 return isChildren(root.left, p) || isChildren(root.right, p);
27         }
28         return false;
29     }

 

  方法二、

    采用递归查找。

    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 == null)
            return right;
        if(right == null)
            return left;
        // 分别在左右子树
        return root;
    }

 

  方法三、

    采用 Map 存储每个节点和该节点的父节点。

    最终采用 Set 存储 p 的所有祖先节点,q依次向祖先节点移动,找出第一次出现在 Set 中的节点即为 p、q 最小祖先节点。

 1   public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
 2         HashMap<TreeNode, TreeNode> parent = new HashMap<>();
 3         Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
 4         parent.put(root, null);
 5         stack.push(root);
 6         
 7         // paretn 同时包含 p、q 则跳出循环 
 8         while(!parent.containsKey(p) || !parent.containsKey(q)) {
 9             TreeNode node = stack.pop();
10             if(node.left != null) {
11                 parent.put(node.left, node);
12                 stack.push(node.left);
13             }
14             
15             if(node.right != null) {
16                 parent.put(node.right, node);
17                 stack.push(node.right);
18             }
19         }
20         
21         Set<TreeNode> ancestors = new HashSet<>();
22         while(p != null) {
23             ancestors.add(p);
24             p = parent.get(p);
25         }
26         while(!ancestors.contains(q)) 
27             q = parent.get(q);
28         return q;
29     }

 

posted @ 2018-11-10 14:28  skillking2  阅读(147)  评论(0编辑  收藏  举报