236. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
“The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Solution1:post-order / 分治 递归

思路:因为题目中是说给given two nodes,说明并一定在tree里面 且 是reference所以不会有重复多次匹配情况。
所以可以比较巧妙地 分治divide只分别关注sub_left_tree和sub_right_tree中先碰到的任意两者之一的位置,conquer时情况1如果左右都找到(必定一个是p一个是q的位置)则向上返回当前root作为目前LCA,情况2如果左或右只找到一个位置(说明两个都在这个位置的子树下 或是 只有一个在) 就向上返回这个位置(以后这个位置会被更新if 另一个在别的地方找到(那个root点的情况1))。
Time Complexity: O(N) Space Complexity: O(N) 递归缓存

Solution2:Iterative

思路:iterative 遍历的同时需要将parent关系保存下来
(1) 建立parent map
(2) 在parent中寻找p q 的 LCA

236. Lowest Common Ancestor of a Binary Tree_第1张图片
屏幕快照 2017-09-08 下午1.15.50.png

Time Complexity: O(N) Space Complexity: O(N)

Solution3:post-order / 分治 递归 自Round1

Time Complexity: O(N) Space Complexity: O(N) 递归缓存

Solution1 Code:

class Solution1 {
    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;
        else if (right == null)
            return left;
        else
            return root;
    }
}

Solution2 Code:

public class Solution2 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        Map parent = new HashMap<>();
        Stack stack = new Stack();
        
        parent.put(root, null);
        stack.push(root);
        while (!parent.containsKey(p) || !parent.containsKey(q)) {
            TreeNode node = stack.pop();
            if (node.left != null) {
                parent.put(node.left, node);
                stack.push(node.left);
            }
            if (node.right != null) {
                parent.put(node.right, node);
                stack.push(node.right);
            }
        }
        
        Set ancestors = new HashSet<>();
        while (p != null) {
            ancestors.add(p);
            p = parent.get(p);
        }
        
        while (!ancestors.contains(q))
            q = parent.get(q);
        return q;
    }
}

Solution3_Round1 Code:

class Solution {
    
    class Pack {
        public boolean p;
        public boolean q;

        Pack() {
            p = false;
            q = false;
        }
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return dfs(root, p, q, new Pack());
    }
    
    private TreeNode dfs(TreeNode root, TreeNode p, TreeNode q, Pack pack) {
        // terminal
        if(root == null) return null;
        
        // divide
        Pack pack_left = new Pack();
        TreeNode result_left = dfs(root.left, p, q, pack_left);
        if(result_left != null) return result_left;
        
        Pack pack_right = new Pack();
        TreeNode result_right = dfs(root.right, p, q, pack_right);
        if(result_right != null) return result_right;
        
        // conquer
        pack.p = pack_left.p || pack_right.p;
        pack.q = pack_left.q || pack_right.q;
        
        if(root == p) {
            pack.p = true;
        }
        else if(root == q) {
            pack.q = true;
        }
        
        if(pack.p && pack.q) {
            return root;
        }
        return null;
        
    }
}

你可能感兴趣的:(236. Lowest Common Ancestor of a Binary Tree)