I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 638 posts at DZone. You can read more from them at their website. View Full User Profile

Thursday Code Puzzler: Lowest Common Ancestor

03.07.2013
| 2868 views |
  • submit to reddit

Thursday is code puzzler day here at DZone. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.

Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer.  It's all about the participation!

Do you have code puzzlers that you'd like to share with the DZone community?  If so, please submit here. 

Find the Lowest Common Ancestor in a Binary Search Tree

Given a binary search tree, find the lowest common ancestor of two nodes on the tree. Wikipedia defines  the lowest common ancestor as follows: 

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



Catch up on all our previous puzzlers here.

 

Comments

Michael Gomez replied on Thu, 2013/03/07 - 4:33pm

Basically mutated the standard binary search algorithm to find the node which is greater than the low input and smaller than the big input.  BNode::hasChild only exists to double check that both inputs actually exist at all.

class BNode{
public:
  int self_val;
  BNode *left;
  BNode *right;
  bool hasChild(int val)
  {
    //standard binary search
    if (self_val < val)
      return left->hasChild(val);
    else if (self_val > val)
      return right->hasChild(val);
    else
      return self_val == val;
  }
};

BNode* findMinRoot(BNode *root, int low, int high)
{
  //find which half of the tree we can eliminate
  if (root->self_val > high)
    return findMinRoot(root->left, low, high);
  else if (root->self_val < low)
    return findMinRoot(root->right, low, high);
  //only return a value iff low and high actually exist
  else
    return (root->hasChild(low) && root->hasChild(high)) ? root:NULL;
}

Régis Décamps replied on Fri, 2013/03/08 - 7:36am

Going bottom-up from v, this is simply the first anchestor of v whose parent is greater than w (assuming v<w and the Node tructure provides parent).

def lowest_common_anchestror(v, w):
    if v > w:
        v, w = w, v
    x = v
    while x is not None and x.parent < w:
        x = x.parent
    return x

The complexity will be the height between the common ancestror and v.

    

Michael Gomez replied on Fri, 2013/03/08 - 11:06am in response to: Régis Décamps

 I never thought of adding a parent reference to each node.... that does make it a lot faster.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.