Leetcode-lowest Common Ancestor of a Binary Tree depth analysis

Source: Internet
Author: User


Given a binary tree, find the lowest common ancestor (LCA) of the Given nodes in the tree.

According to the definition of the LCA in Wikipedia: "The lowest common ancestor is defined between," nodes V and W as the L Owest node in T, have 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 nodes5and1Is3. Another example is LCA of nodes5and4Is5, since a node can be a descendant of itself according to the LCA definition.

Deep analysis of this problem, because this problem can draw a lot of binary tree knowledge.

1) Obviously, if each node has a parent pointer, it is convenient to find it upward. But the problem is obviously not

2) The second kind is also relatively good to think, as follows:

i) if the p,q is in the left subtree of root, continue looking in the left sub-tree.

II) If the p,q are all in the right subtree of root, continue looking in the right sub-tree.

III) Otherwise, the current root is the request, return.

Another helper method is required to determine if a node is a node in another nodes subtree.

Public TreeNode lowestcommonancestor (TreeNode root, TreeNode p, TreeNode q) {    if (covers (Root.left, p) && Cove RS (Root.right, q)) return Lowestcommonancestor (Root.left, p, q);    if (Covers (Root.right, p) && covers (Root.right, q)) return Lowestcommonancestor (Root.right, p, q);    return root;    }        Private Boolean covers (TreeNode root, TreeNode p) {    if (root = = p) return true;    if (root = null) return false;    Return Covers (Root.left, p) | | Covers (Root.right, p);    }

The code is very brief, but unfortunately timed out, the reason, a lot of nodes are repeatedly visited.

3) Another idea is to save the path from root to P or Q node and then compare two linked lists, at which point a helper method is needed to find the path from root to P,q

Public TreeNode LowestCommonAncestor1 (TreeNode root, TreeNode p, TreeNode q) {    list<treenode> LISTP = Getnodepa Th1 (root, p);    list<treenode> Listq = getNodePath1 (root, q);        for (int i = 0; i < listp.size () && i < listq.size (); i++) {    if (listp.get (i)! = Listq.get (i)) {    ret Urn Listp.get (i-1);    }    }    return null;    }        Public list<treenode> getNodePath1 (TreeNode root, TreeNode p) {    list<treenode> List = new arraylist< Treenode> ();    if (p = = NULL | |!covers (root, p)) return list;    while (root! = p) {    list.add (root);    if (Covers (Root.left, p)) root = Root.left;    else if (covers (Root.right, p)) root = Root.right;    }    List.add (p);    return list;    }        Private Boolean covers (TreeNode root, TreeNode p) {    if (root = = p) return true;    if (root = null) return false;    Return Covers (Root.left, p) | | Covers (Root.right, p);    }

Must be timed out because Getnodepath is repeatedly accessed as a combination of covers.

So now the optimization goal is to be able to do without repeated access to the situation, the 2 and 3 optimization. Now you can look at the previous question, to determine whether a tree is a balanced binary tree, http://blog.csdn.net/my_jobs/article/details/47663845. You can see the final summary, not the traversal of the tree from the top down, but from the bottom up, and at this point only need to add a flag bit or add a return value.

So for 2) 3) the optimization is there.

4) First look at the optimization of 3):

public TreeNode LowestCommonAncestor2 (TreeNode root, TreeNode p, TreeNode q) {LIST<TR    eenode> LISTP = new arraylist<treenode> ();        list<treenode> LISTQ = new arraylist<treenode> ();    GetNodePath2 (LISTP, Root, p);        GetNodePath2 (LISTQ, Root, Q);    int i = Listp.size ()-1;    Int J = listq.size ()-1;    while (i >= 0 && J >= 0) {if (Listp.get (i)! = Listq.get (j)) return Listp.get (i+1);    i--;    j--; } return i+1 >= 0? Listp.get (i+1): j+1 >= 0?    Listq.get (j+1): null; } public boolean getNodePath2 (list<treenode> List, TreeNode root, TreeNode p) {if (root = null) return False    ;    if (root = = p) {list.add (root);    return true;    } if (GetNodePath2 (list, Root.left, p)) {list.add (root);    return true;    } if (GetNodePath2 (list, root.right, p)) {list.add (root);    return true;    } return false; }
Finally AC, the optimization scheme for this problem is to return true when the node is found, and the upper layer of the recursive call will definitely return the result to determine if left,right is on this path.

5) Optimization of the second look to 2)

    Public TreeNode LowestCommonAncestor3 (TreeNode root, TreeNode p, TreeNode q) {    if (root = null | | root = = P | | root = = q) return root;    TreeNode left = LowestCommonAncestor1 (Root.left, p, q);    TreeNode right = LowestCommonAncestor1 (Root.right, p, q);    return left! = null? Right! = null? Root:left:right;     }

The code is more streamlined, as in 4), and if this node is found in the underlying recursion, it will go up, if not empty, certainly for node. Finally, if one is empty, how do you explain that this node contains only one of the p,q, and if two are not empty, then this node is the desired. Because this method is from the bottom up, so the first encounter of the node is the request!!!


According to the above two optimization schemes and judging whether a tree is a balanced binary tree three ways, you can see the tree of this kind of problem optimization strategy: from top to bottom change from bottom up !!!

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Leetcode-lowest Common Ancestor of a Binary Tree depth analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.