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