1. Not a binary search tree,
http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1
Time complexity of the above solution is O(n)Attempt#1
Attempt#2
http://articles.leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
_______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4
the LCA of nodes 5and 1 is 3.
Please note that LCA for nodes 5 and 4 is 5.
Please note that LCA for nodes 7 and 4 is 2. (although 5,3 are also ancestors, but not the lowest)
2. binary search tree, we could do a modified find on the two nodes and see where the paths diverge.
http://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree/
Time complexity is O(h) where h is height of tree
Recursive, Iterativehttp://algorithms.tutorialhorizon.com/files/2014/11/LCA-in-Binary-Search-Tree.png
Recursive, Iterativehttp://algorithms.tutorialhorizon.com/files/2014/11/LCA-in-Binary-Search-Tree.png
// LCA for Binary Tree // Time:O(n) // 1. Recursive #1 public TreeNode LCA(TreeNode root, TreeNode p1, TreeNode p2) { if ( isChild(root.left, p1) && isChild(root.right, p2) ) return LCA(root.left, p1 ,p2); if ( isChild(root.right,p1) && isChild(root.right,p2) ) return LCA(root.right, p1,p2); return root; } private boolean isChild(TreeNode root, TreeNode p) { if (root == null) return false; if (root == p) return true; return isChild(root.left, p) || isChild(root.right, p); } // 2. Recursive #2 // Case1: If there are two nodes on one of the sides, then we have // to check if the child node on this side is p or q (because in this // case the current node is the common ancestor). // If the child node is neither p nor q, we should continue to search // further (starting from the child). // Case2: If one of the searched nodes (p or q) is located on the right // side of the current node, then the other node is located on the other // side. Thus the current node is the common ancestor public class Solution { static int TWO_NODES_FOUND = 2; static int ONE_NODE_FOUND = 1; static int NO_NODE_FOUND = 0; public TreeNode LCA(TreeNode root, TreeNode p1, TreeNode p2) { // Same node and only node node below if ( p2 == p1 && (root.left == p2 || root.right == p1) ) return root; int nodesFromLeft = isChild(root.left, p1,p2); if ( nodesFromLeft == TWO_NODES_FOUND ) { if (root.left == p1 || root.left == p2) return root.left; else return LCA(root.left, p1,p2); } else if ( nodesFromLeft == ONE_NODE_FOUND ) { if (root == p) return p; else if (root == q) return q; } int nodeFromRight = isChild(root.right, p1, p2); if ( nodeFromRight == TWO_NODES_FOUND ) { if (root.right == p1 || root.right == p2) return root.left; else return LCA(root.right, p1,p2); } else if ( nodeFromRight == ONE_NODE_FOUND ) { if (root == p) return p; else if (root == q) return q; } if ( nodeFromLeft == ONE_NODE_FOUND && nodeFromRight == ONE_NODE_FOUND ) return root; else return null; } // Check how many nodes (p1, p2 ,p1 and p2, none) under this root // Output: 0(NO_NODES_FOUND),1(ONE_NODE_FOUND),2(TWO_NODES_FOUND) private int isChild(TreeNode root, TreeNode p1, TreeNode p2) { /* int ret= NO_NODES_FOUND; if (root==null) return NO_NODES_FOUND; if (root == p1 || root == p2) ret+=1; // isChild(root.left..) || isChild(root.right,..) ret += isChild(root.left, p1,p2); if ( ret = TWO_NODES_FOUND ) //FOUND p1 and p2 { return ret; } return ret + isChild(root.right, p1, p2); */ int ret = 0; ret += isChild(root, p1)?1:0; ret += isChild(root, p2)?1:0; return ret; } private boolean isChild(TreeNode root, TreeNode p) { if (root == null) return false; if (root == p) return true; return isChild(root.left, p) || isChild(root.right, p); } }
// LCA for Binary Search Tree // Time :O(logn) = O(h), h is the height of the tree // 1. Recursive Space:O(n) public TreeNode LCA(TreeNode root, TreeNode p1, TreeNode p2) { // Base case if ( root == null ) return null; if ( root.val > p1.val && root.val > p2.val ) return LCA( root.left, p1, p2 ); else if ( root.val < p1.val && root.val < p2.val ) return LCA( root.right, p1, p2); return root; } // 2. Iterative Space:O(1) public TreeNode LCA(TreeNode root, TreeNode p1, TreeNode p2) { while ( root != null ) { if ( root.val > p1.val && root.val > p2.val ) root = root.left; else if ( root.val < p1.val && root.val < p2.val ) root = root.right; else break; } return root; }3. similar Ones
No comments:
Post a Comment