30 Day Risk-Free Guarantee:
100% money back if you're unsatisfied.
Book (308 Pages):
  • 150 Programming Interview Questions and Solutions
  • Five Proven Approaches to Solving Tough Algorithm Questions
  • Ten Mistakes Candidates Make -- And How to Avoid Them
  • Steps to Prepare for Behavioral and Technical Questions
  • Interview War Stories: A View from the Interviewer's Side
  • Book Preview and More Info

Video (One Hour):
  • Watch CareerCup's founder perform a totally unscripted technical interview of a candidate.
  • Overview of what interviewers look for in software engineering jobs.
  • Technical questions with white-boarding coding where the candidate does well - and struggles.
  • Interviewer reviews with what went well and poorly.
  • Video Preview and More Info

Resume Review (24 - 48hr)
  • Get your resume reviewed by a trained engineering interviewer. More Info
All Products / Services


Express Prep Package (Book)
$29.99 for e-book | $32.45 for paperback
Buy E-Book Buy on Amazon


Standard Prep Package (E-Book & Video)
Emailed Instantly | $39.99
Buy Standard

Elite Prep Package (E-Book, Video & Resume)
Emailed Instantly | $99.99
Buy Elite
 



Given 2 nodes in a binary tree (not a binary search tree), find the first common parent node. You are not allowed to store any nodes in a data structure.

32


king_k on July 09, 2008 |Edit | Edit

is the node typical sturcuture with left and right? or some other representation?

Anonymous on July 09, 2008 |Edit | Edit

node* LCA(node* root, node* nd1, node* nd2){

if(root==NULL)
return NULL;

if(root->left==nd1 || root->right==nd1 || root->left==nd2 || root->right==nd2)
return root;

node* lc = LCA(root->left,nd1,nd2);
node* rc = LCA(root->right,nd1,nd2);

if(lc!=NULL && rc!=NULL)
return root;

if(lc==NULL) return rc;
else return lc;
}

anon on July 09, 2008 |Edit | Edit

Yes, typical binary tree - each node has a left and right node pointer, as well as a pointer to it's parent.

Anonymous - you cannot take as a parameter the root.

My solution (after being told that I cannot store each parent in a hash table was to raise the lower of the 2 nodes to the level of the other node, and traverse up the tree until r->parent == l->parent)

Anonymous on July 09, 2008 |Edit | Edit

sorry it should have been ...

node* LCA(node* nd, node* nd1, node* nd2){

if(nd==NULL)
return NULL;

if(nd->left==nd1 || nd->right==nd1 || nd->left==nd2 || nd->right==nd2)
return nd;

node* lc = LCA(nd->left,nd1,nd2);
node* rc = LCA(nd->right,nd1,nd2);

if(lc!=NULL && rc!=NULL)
return nd;

if(lc==NULL) return rc;
else return lc;
}

and call
node* parent = LCA(root, nd1, nd2);

Anonymous on August 06, 2008 |Edit | Edit

This is not correct. Suppose you want to find the LCA of the root and another node. Can your program return the right answer?

Anonymous on October 01, 2008 |Edit | Edit

yes it would return to null.... root isnt ancestor of itself

ppp on October 06, 2008 |Edit | Edit

this is not correct, assume that it stops at the root node. root->l == d1, but you might not find d2 in the right subtree of root.

"if(nd->left==nd1 || nd->right==nd1 || nd->left==nd2 || nd->right==nd2) return nd;"

search(node* root, node* d1, node* d2) {
node1 = searchR(root->l, d1, d2);
node2 = searchR(root->r, d1, d2);
if (node1 && node2) { pirnt root;}
}

node* searchR(node* root, node* d1, node* d2) {
if (root == 0) {return 0;}
if (root == d1 || root == d2) return root;
node1 = searchR(root->l, d1, d2);
node2 = searchR(root->r, d1, d2);
if ( node1 && node2) {print root; return root;}
else if (node1 != 0) {return node1;}
else {return node2;}
}

contact.jbhalla on July 10, 2008 |Edit | Edit

another one:-
Node * LCA(Node *t , Node *n1,Node * n2)
{
if (!t) return NULL ;

if ((n1->val < t->val)) && (n2->val < t->val))
return LCA(t->left,n1,n2);

if ((n1->val > t->val)) && (n2->val > t->val))
return LCA(t->right,n1,n2);

if ( (n1->val <= t->val)) && (n2->val >= t->val))
return t;
}

what on August 01, 2008 |Edit | Edit

is this right ? i am not sure .. since it seems its doing compares, it seems the question clearly states that its not a BST and its a normal binary tree.

what on August 01, 2008 |Edit | Edit

is this right ? i am not sure .. since it seems its doing compares, it seems the question clearly states that its not a BST and its a normal binary tree.

I hate this captcha, they are keeping the images so complex that it takes 5-6 tires to get it right .. please remove this .. its more of a pain than useful.

Anonymous on August 01, 2008 |Edit | Edit

it will work only for BST

Anonymous on August 01, 2008 |Edit | Edit

it will work only for BST

anon on July 10, 2008 |Edit | Edit

Remember - you only have node1 and node2 at the start. Each node contains a reference to the parent, so you can get the root by traversing to the root, but you start out with only node1 and node2.

Anonymous1 on July 11, 2008 |Edit | Edit

node* LCA(node* nd1, node* nd2){

node* cur1 = nd1;
node* cur2 = nd2;

// calculate nd1 height
int nd1_height = 0;
while(cur1->parent!=NULL){
nd1_height++;
cur1 = cur1->parent;
}

// calculate nd2 height
int nd2_height = 0;
while(cur2->parent!=NULL){
nd2_height++;
cur2 = cur2->parent;
}

int diff = nd1_height - nd2_height;

cur1 = nd1;
cur2 = nd2;

if(diff>0){
while(diff--){
cur1 = cur1->parent;
}
} else{
diff = -diff;
while(diff--){
cur2 = cur2->parent;
}
}

while(1){
if(cur1==NULL || cur2==NULL) break;
if(cur1 == cur2)
return cur1;
cur1 = cur1->parent;
cur2 = cur2->parent;
}

return NULL;
}

acoader on November 04, 2008 |Edit | Edit

This is a very good algorithm - to figure out the depths and then 2 pointers. Runtime is O(h) - h is the tree height

king_k on July 12, 2008 |Edit | Edit

while calculating the height of node1 and node2...we can check if the other node comes on the way to the root...if yes then return that immediatley...

anon on July 13, 2008 |Edit | Edit

In this case, 'node2' is a parent of 'node1', so returning it would not be correct - because 'node2' cannot be a parent of itself.

tb on July 12, 2008 |Edit | Edit

Google tarjan's offline LCA algorithm

toobad on July 26, 2008 |Edit | Edit

People really misguide and confuse. The question clearly states its not a BST, but lot of people have given solution assuming its a BST. Its easy to do in a BST.

toobad on July 26, 2008 |Edit | Edit

also i see another solution that talks about parent pointer. Does a normal binary tree have parent pointer ? no is the clear answer.

So the solution should be for a Binary Tree (not BST) , (of course that can be unbalanced, and incomplete)), which means there is only a left and right pointer. No parent or up, no rule that left should be less than parent and right greater than parent. - so a simple binary tree.

Somehow people have byhearted solutions and they dump that in interviews and they get selected.

anonymous on August 12, 2008 |Edit | Edit

toobad,

let us consider the worst case of the nodes not having the pointers to its parents, the tree is unbalanced and incomplete . And, ofcourse, it is not a BST..do you have any solution my your mind..this would definitely increase the complexity of the problem...I am working on it...If I get a solution, I would definitely post it here.

anonymous on August 12, 2008 |Edit | Edit

toobad,

let us consider the worst case of the nodes not having the pointers to its parents, the tree is unbalanced and incomplete . And, ofcourse, it is not a BST..do you have any solution in your mind..this would definitely increase the complexity of the problem...I am working on it...If I get a solution, I would definitely post it here.

(a typo in my previous comment)

violinlakshmi on August 15, 2008 |Edit | Edit

what anonymous said is true,but I was not able to come up with a solution for a binary tree. So the following program is assuming a BST and the program is to find the common nodes of the two nodes given.

/*Given 2 nodes in a binary tree (not a binary search tree), find the first common parent node.
You are not allowed to store any nodes in a data structure.*/

#include <stdio.h>
#include <stdlib.h>

struct NODE{
int data;
struct NODE* left;
struct NODE* right;
};

typedef struct NODE* node;

node constructBST(node root,int data){
node cur,mytemp;

if(!root){
node temp;
temp=(node)malloc(sizeof(struct NODE));
temp->data=data;
temp->left=NULL;
temp->right=NULL;
root=temp;
return root;
}

cur=root;
while(cur->data>data){
if(cur->left)
cur=cur->left;
else
break;
}

while(cur->data<=data){
if(cur->right)
cur=cur->right;
else
break;
}

if(data<cur->data){
mytemp=(node)malloc(
sizeof(struct NODE));
mytemp->data=data;
mytemp->left=NULL;
mytemp->right=NULL;
cur->left=mytemp;
}

if(data>cur->data){
mytemp=(node)malloc(
sizeof(struct NODE));
mytemp->data=data;
mytemp->left=NULL;
mytemp->right=NULL;
cur->right=mytemp;
}

return root;
}

int deapth(node root, node node1){
node cur;
int len=0;

if(!root){
printf("\nEmpty list");
return(0);
}
cur=root;
while(node1->data<=cur->data){
if(cur->left){
cur=cur->left;
len++;
}
else
break;
}

while(node1->data>cur->data){
if(cur->right){
cur=cur->right;
len++;
}
else break;
}
return len;
}

node findCommonParent(node root,node node1,node node2){
int data1,data2;
node larger,smaller;
node cur;
cur=root;

if(!cur){
printf("\nEmpty List");
return NULL;
}

data1=node1->data;
data2=node2->data;
if(data1>data2){
larger=node1;
smaller=node2;
}
else{
larger=node2;
smaller=node1;
}

while(cur->data > larger->data){
if(cur->left)
cur=cur->left;
else
break;
}

while(cur->data <= smaller->data){
if(cur->right)
cur=cur->right;
else
break;
}

//printf("\n The common parent is %d ",cur->data);
return cur;
}

int main()
{
int i=0;
node root,commonParent,node1,node2;
commonParent=NULL;
root=NULL;
node1=(node)malloc(sizeof(struct NODE));
node2=(node)malloc(sizeof(struct NODE));
node1->data=1;
node2->data=3;
i=5;
root=constructBST(root,i);
i=2;
root=constructBST(root,i);
i=3;
root=constructBST(root,i);
i=1;
root=constructBST(root,i);
i=9;
root=constructBST(root,i);
i=7;
root=constructBST(root,i);
i=11;
root=constructBST(root,i);
commonParent=findCommonParent(root,node1,node2);
printf("\n The common parent is %d \n",commonParent->data);
return 0;
}

acoader on November 03, 2008 |Edit | Edit

this code does not have comments, so its hard to figure out what it does. Also, seems like its constructing a BST, which is not part of the question... It would be great if the author explained what is being done..

nanmaga on October 31, 2008 |Edit | Edit

Since we are not allowed to store the nodes in a DS, the first thing that comes to my mind is the traversals. We can find the common root from two traversals.

Construct the preorder and inorder traversals. The common root is the one which has the follg two properties:
a) Should be present in between the two nodes in the inorder traversal
b) If there is more than one in a), then the common root is the one which occurs the left-most in the pre-order traversal.

We need not store the nodes per se in the DS but just their values from the traversals in say a array/vector...I believe thats allowed...

nanmaga on November 05, 2008 |Edit | Edit

Just realized, the method using traversals doesn't work in all cases. Say, if the tree has only left children...then all traversals gives us the same sequence and its not possible to find the common node...So, I guess the only way is through the RMQ method...using DP...

acoader on November 04, 2008 |Edit | Edit

How about this- travel along the path from one of the 2 nodes to the root, and check each time if the other node occurs in the other subtree, i.e., if current node is left child, check the right child subtree or vice-versa.

Let the nodes be (a,b)

findLca( Node *a, Node *b )
{
bool found = false;
Node *p = findParentOf( a );

//try finding b in the tree rooted at p->left
if ( findNodeIn( b, p->left ) ) {
return p;
}
Node *otherSubTree = p->right;

// the other node has to be in otherSubTree
// or a subtree of an ancestor of p, unless
// the other node is p itself, in which case
// return its parent
while ( 1 ) {
if ( findNodeIn( b, otherSubTree ) ) {
return p;
}

// Here we know LCA is either p or
// in a subtree of p's ancestor
Node *newP = findParentOf( p );
if ( !newP || p == b ) {
return newP;
}
if ( p == newP->left ) {
otherSubTree = newP->right;
}
else {
otherSubTree = newP->left;
}
p = newP;
}
}

Devil170 on February 15, 2009 |Edit | Edit

Why do people get carried away and give all kind of weirdo answers! and half of the page long codes dont make any sense without description. Please avoid doing that.

Coming to the problem. We know that root is not given and it is not a BST. But one thing is that it has pointer to the parent.

*This problem is similar to finding the intersection of two linked lists*.
Now use the same logic of finding the intersection of two linked lists here and find it. you would get it.

peace on November 14, 2009 |Edit | Edit

Devil170,

This requires you to have parent pointers. What if we are not given that, you cant store them as they violate the constraint:"no additional DS"

SK on April 23, 2009 |Edit | Edit


LCA(*node A, *node B){
*node t1 = A;
*node t2 = B;

while (t1 != t2){
if (t2->parent == null)
if (t1-> parent == null)
return NoCommonParent
else
t1 = t1->parent;
else
t2=t2->parent;
}
return t1;

}

Kiran on August 06, 2009 |Edit | Edit

node* LCA(node* root, int a, int b)
{
if (!root || root->data == a || root->data == b)
return NULL;

node* lcaNode = NULL;
int tmp = findLCA(root, a, b, &lcaNode);
return lcaNode;
}

int findLCA(node* root, int a, int b, node** lcaNode)
{
if (!root)
return 0;
int l = findLCA(root->left, a, b, lcaNode);
int r = findLCA(root->right, a, b, lcaNode);

if (l + r == 2)
{
if (*lcaNode == NULL)
{
*lcaNode = root;
}
return 2;
}
else
{
return l + r + ((root->data == a) || (root->data == b) ? 1 : 0);
}
}

RahulParundekar on March 02, 2010 |Edit | Edit

Properties:
1. Binary tree. not necessarily BST.
2. No parent node;

---code---


class Ancestor{
static Node leftNode,rightNode;
static String leftCode,rightCode;
static private void inorderTraversal(Node n, String code){
if(n==leftNode)
leftCode=code;

if(n==rightNode)
rightCode=code;

if(n.left!=null)
inorderTraversal(n.left,code + "0");

if(n.right!=null)
inorderTraversal(n.right,code + "1");

}

static public Node findCommonAncestor(Node root, Node left, Node right){
leftNode=left; rightNode=right;
inorderTraversal(root,""); //empty string
Nodeparent=root;
for(int i=0;i<leftCode.length&&i<rightCode.length;i++)
{
if(leftCode.charAt(i)!=rightCode.charAt(i))
break;
else{
if(leftCode.charAt(i)=='0')
parent = parent. left;
else
parent = parent. right;
}
}
if(i==leftCode.size()||i==rightCode.size())
return null;
else
return parent;
}
}

Add a Text Comment | Add Runnable Code
Name:
Comment:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.








Amazon (1033)Bloomberg LP (403)Qualcomm (117)Adobe (88)Goldman Sachs (78)NetApp (49)IBM (43)Morgan Stanley (33)CapitalIQ (30)Sophos (25)Achieve Internet (23)Electronic Arts (19)Motorola (18)Research In Motion (17)Flipkart (16)
Microsoft (867)Google (141)NVIDIA (98)Yahoo (82)Epic Systems (69)Expedia (47)VMWare Inc (43)Apple (32)Cisco Systems (28)Facebook (23)Infosys (22)Agilent Technologies (19)Sage Software (17)Deshaw Inc (16)FlexTrade (15)
More Companies »
Software Engineer / Dev... (1062)Financial Software Deve... (170)Testing / Quality Assur... (56)Analyst (35)Virus Researcher (25)Field Sales (15)Developer Program Engin... (9)Front-end Software Engi... (6)MyJoB (5)area sales manager (4)Assistant (3)Cabin crew (2)Accountant (1)personnel (1)Intern (1)
Software Engineer in Te... (288)Program Manager (65)Development Support Eng... (47)INTERN(MSIDC) (28)Web Developer (18)System Administrator (10)Consultant (10)Production Engineer (5)Associate Technology L2 (5)AcquireKnowledge (4)Product Security Engine... (3)Solutions Architect (2)Gamer (1)mts (1)Fresh graduate interview (0)
More Job Titles »
Algorithm (1073)Terminology & Trivia (294)C (166)Object Oriented Design (159)Java (121)Testing (114)Arrays (101)Operating System (78)Database (70)Linked List (62)String Manipulation (56)Networking / Web / Inte... (44)Threads (36)Linux Kernel (33)PHP (22)
Coding (511)C++ (204)Behavioral (159)Data Structures (155)Experience (116)Brain Teasers (111)Computer Architecture &... (79)General Questions and C... (73)Trees and Graphs (69)Math & Computation (57)Application / UI Design (45)Ideas (38)System Design (35)Puzzles (30)Bit Manipulation (20)
More Topics »
CareerCup Official Interview Book Daily Questions Requests for Help Mock Interviews Video for Cracking the Coding Interview Job Placement Service CareerCup Blog
My Profile Edit Profile & Email Settings Sign Out