Common ancestor--binary Tree

Source: Internet
Author: User

Find the first common ancestor of two node in binary tree. Attention is not necessarily BST

Idea: The p,q are all in the left subtree, and they are branch. If it's all right, then branch. If you are not in same side, return to first common ancestor so the main is to find two node subtree subtree in left Solution1:from and right cc150 because the covers function is called 2n Nodes (n for left side and N nodes for right side). Then if on the same side, will continue to recursive search, also need check covers, call 2N/2 times, and then 2N/4 times ... Time:o (2n) + O (2N/2) + O (2N/4) + ... = O (N)
1  Public StaticTreeNode CommonAncestor2 (TreeNode root, TreeNode p, TreeNode q) {2     if(!covers (Root, p) | |!covers (root, Q)) {//Error check-one node isn't in tree3         return NULL;4     }5     returnHelper (root, p, q);6 }7 Private StaticTreeNode Helper (TreeNode root, TreeNode p, TreeNode q) {8     if(Root = =NULL)return NULL;9     Ten     BooleanIs_p_on_left =Covers (Root.left, p); One     BooleanIs_q_on_left =Covers (Root.left, q); A      -     if(Is_p_on_left! =is_q_on_left) { -         //nodes is on different side the         returnRoot; -     } -TreeNode child_side = is_p_on_left?Root.left:root.right; -      +     //Search in subtree -     returnHelper (Child_side, p, q); +  A  at } - //Check whether P is a descendent of root - Private Static BooleanCovers (TreeNode root, TreeNode p) { -     if(Root = =NULL)return false; -      -     if(root = = p)return true; in      -     returnCovers (Root.left, p) | |Covers (Root.right, p); to}
View Code

Similar solution http://xixiaogualu.blogspot.com/2013/09/lowest-common-ancestor-of-binary-tree.html

Top-bottom from top to bottom:

     Public StaticTreeNode LCA1 (TreeNode root,treenode n1,treenode n2) {if(exist (ROOT.LEFT,N1) &&(exist (ROOT.LEFT,N2))) {            //find in left subtree            returnLCA1 (Root.left, N1, N2); }                if(exist (ROOT.RIGHT,N1) &&(exist (ROOT.RIGHT,N2))) {            returnLCA1 (Root.right, N1, N2); }                returnRoot; }    //find in subtree from root     Public Static Booleanexist (TreeNode root, TreeNode N) {if(Root = = N)return true; if(Root = =NULL)return false; returnexist (Root.left,n) | |exist (root.right,n); }
View Code

Solution2: Improving the above solution from cc150

bottom-up , using the return value of the commonancestor to reduce the number of search down, recursive invocation.

There are several possible cases where the return value is:

Commonancestor (TreeNode root, TreeNode p, Trenode Q) return p, if root ' s subtree includes P (and not Q) return q, if Roo T ' s subtree includes q (and not p) return null, if Neighter p nor Q in root ' s subtree else return common ancestor of p a nd q
1  Public StaticTreeNode LCA (TreeNode root, TreeNode p, TreeNode q) {2         if(Root = =NULL)return NULL;3         if(root = = P | | root = =q) {4             5             returnRoot;6         }7         8         //is child of root9         if(p = = Root.left && q = = Root.right | | p = = Root.right && Q = =root.left) {Ten             returnRoot; One         } A          -         //search in left and right subtree -TreeNode left =LCA (Root.left, p, q); theTreeNode right =LCA (Root.right, p, q); -          -         if(Left! =NULL&& Right! =NULL){ -             //subtree and the other are in right +             returnRoot; -         } +         if(Left! =NULL){ A             returnLeft ; at         } -         if(Right! =NULL){ -             returnRight ; -         } -         return NULL; -}
View Code

Expansion: if P or Q is not node in the tree, the bottom up method will cause problems

The idea is that if you use this return value to differentiate between the two cases: case 1:p was a child of Q (or, Q was a child of P) case 2:p was in the tree and Q was not (or, Q was in T He tree and P is not) both cases would return p. but case 2 actually was not ancestor, should was null.Use the helper class to tag Case2 with a Boolean isancestor
Class Result{public TreeNode Node;public boolean isancestor;public Result (TreeNode N, boolean Isanc) {node = N;isancestor = Isanc;}}

 

public static TreeNode CommonAncestor3 (TreeNode root, TreeNode p, TreeNode q) {Result res = helper (root, p, q); if (Res.isan cestor) {return res.node;} return null;}

  

1 Private StaticResult Helper (TreeNode root, TreeNode p, TreeNode q) {2     if(Root = =NULL){3         return NewResult (NULL,false);4     }5     if(Root = = P && root = =q) {6         return NewResult (Root,true);7     }8     9Result left =Helper (Root.left, p, q);Ten     if(left.isancestor) { One         returnLeft ; A     } -Result right =Helper (root.right, p,q); -     if(right.isancestor) { the         returnRight ; -     } -     //Find common ancestor -     if(Left.node! =NULL&& Right.node! =NULL){ +         return NewResult (Root,true); -}Else if(root = = P | | root = =q) { +         /*If we ' re currently at p or Q, and we also found one of the those A nodes in a subtree, then this is truly an ancestor and the at flag should be true.*/ -         BooleanIsAncestor = left.node! =NULL|| Right.node! =NULL;  -         return NewResult (root, isancestor); -}Else{ -         // -         return NewResult (Left.node! =NULL? Left.node:right.node,false); in     } -}
View Code

 

With link to parent this requires only trace p and Q ' s parents up until intersect. because p,q may be different level, for example Q in the P- subtree。 So use Hashtable to record the already-trace node. or move to the same level, then move up two pointers at the same time to determine if the same, return the first node of the same time

Common ancestor--binary Tree

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.