美文网首页Interview Questions
236. Lowest Common Ancestor of a

236. Lowest Common Ancestor of a

作者: 宋翰要长肉 | 来源:发表于2016-03-23 15:24 被阅读49次

    Definition of LCA

    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).

    Algorithm 1

    • find path from root to n1
    • find path from root to n2
    • traverse both paths until the nodes are not same, return previous node

    Find a path from root to given node

    • DFS search like preorder traverse in recursive version
    • base case if root is null return false
    • otherwise, if root is the given node return true
    • otherwise, put the node to the end of a LinkedList
    • traverse left-subtree and right-subtree
      • if one of return value of two traversals is true, return true;
      • otherwise, remove the last node in the LinkedList and return false;

    Complexity

    • Time complexity: Worse case O(N) (N is number of nodes in the binary tree)
      • find path: Worse case O(N)
      • find previous node before first different nodes: Worse Case O(H) (H is height of the binary tree)
    • Space complexity: O(H) (H is height of the binary tree)
      • we need a LinkedList to store the path, and the length of path is H

    Code

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            LinkedList<TreeNode> pathToP = new LinkedList<TreeNode>();
            LinkedList<TreeNode> pathToQ = new LinkedList<TreeNode>();
            if (!getPath(root, pathToP, p) || !getPath(root, pathToQ, q)) {
                return null;
            }
            Iterator<TreeNode> traverseP = pathToP.iterator();
            Iterator<TreeNode> traverseQ = pathToQ.iterator();
            TreeNode pre = null;
            while(traverseP.hasNext() && traverseQ.hasNext()) {
                TreeNode curP = traverseP.next();
                TreeNode curQ = traverseQ.next();
                if (curP == curQ) {
                    pre = curP;
                } else {
                    break;
                }
            }
            return pre;
        }
    
        private boolean getPath(TreeNode root, LinkedList<TreeNode> path, TreeNode target) {
            if (root == null) {
                return false;
            }
            path.add(root);
            if (root == target) {
                return true;
            }
            if (getPath(root.left, path, target) || getPath(root.right, path, target)) {
                return true;
            }
            path.removeLast();
            return false;
        }
    

    Algorithm 2

    • traverse the tree start from root
    • if any target nodes matches the root, return root
    • else we traverse the left subtree and right subtree
    • if the root which has a target node in its left subtree and another in its right subtree, the root is LCA
    • if the two target nodes at left subtree, the LCA has been found
    • if the two target nodes at right subtree, the LCA has been found

    Code

     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return LCA(root, p, q);
    }
    
    private TreeNode LCA(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        if (root == p || root == q) {
            return root;
        }
        TreeNode left = LCA(root.left, p, q);
        TreeNode right = LCA(root.right, p, q);
        if (left != null && right != null) {
            return root;
        }
        return (left == null)? right: left;
    }
    

    相关文章

      网友评论

        本文标题:236. Lowest Common Ancestor of a

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