Amazon Interview Question for Software Development Managers


Country: United States
Interview Type: Phone Interview




Comment hidden because of low score. Click to expand.
1
of 1 vote

I have another solution:
Let given node be A, destination node be B
1) from A, traverse up following the pointer to parent until encounter three types of node, let the node be C
a. C is the root node
b. C with value bigger than the destination value
c. C node equals to the destination, then we got the path from A to B, return.
2) do the binary search on the right child tree of C to find B
3) If we find B, concatenate the path A -> C -> B, that's the answer.
The time complexity of this method is O(logN + logN) = O(logN)

- oohtj January 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

My mistake in applying the comment to wrong answer. Ignore the comment in the answer above.

That is not correct. Suppose given pointer is to a node with value 100 (A node), and you are looking for node with value 75 (B Node). Suppose this was the input order in which the tree was constructed

80 75 101 100

starting with 100, you will reach 101 (C Node), at which point your algo would suggest that search in the right child tree of 101. Your search would fail.

- Underdog January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

u r right. that's the bug. thank u a lot.
That's the fix:
1) from A, traverse up until encounter the node C
a. C is the root node
b. C with value between A and B
c. C is the destination, that's the answer
2) from C, if B is larger than C, do the binary search in its right child sub tree; otherwise, search in the left child sub tree
3) concatenate the path A->C->B, that's it.
Time complexity still holds as O(logN).

- oohtj January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It is still not right. Try with this input; A and B as before.

80 75 82 101 100

Your algo would find C = 82, and from there on would fail.

- Underdog January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ooooh, no, to be clarify the b of step 1
b. C is between A and B, and Min (| value(C) - value(B) | ).

Underdog, u have a pair of sharp eyes

- oohtj January 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Min (| value(C) - value(B) | ). what does this mean?

- lodown414 January 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

From oohitj's answer on Jan 01, 2013, change the condition b) and it will work:
1) from A, traverse up until encounter the node C
a. C is the root node
b. B is between A and C
c. C is the destination, that's the answer
2) from C, if B is larger than C, do the binary search in its right child sub tree; otherwise, search in the left child sub tree
3) concatenate the path A->C->B, that's it.
Time complexity still holds as O(logN).

- Larry April 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

//1) traverse from source node to the root node(top/first node) of BST.
At each traversal add the value of each node in a stack (say stack 1)
//2) traverse from the root node(top/first node) of BST to the destination node using InOrder .At each traversal add the value of each node in a stack (say stack 2)
//3) Compare stack1 with stack 2.
//3.1)if a node other than root node is common on both stack, then the path from source to destination will pass through that node skipping the root node. Print the values of stack 1 followed by stack 2.
//3.2)if there is no node other than root node is common on both stack, then the path from source to destination will pass through that root node. Print the values of stack 1 followed by stack 2.

//c#
public void path(Node _node)
{
if (_node == rootNode) { return; }
Stack1.push(_node.value);
path(Node _node.parentNode);
}

public void SearchRecord(Node _node, int _value)
{
if (_node == null) return 0;

if (_value < _node.value)
{
Stack2.push(_node.value);
SearchRecord(_node.leftNode, _value);
}
else if (_value > _node.value)
{
Stack2.push(_node.value);
SearchRecord(_node.rightNode, _value);
}
else if (_value == _node.value)
{
Stack2.push(_node.value);
return;
}
return;
}


public bool compare(Node _stack1Node,Node _stack2Node)
{
bool IsRepeated = false;
while(_stack1Node!= null)
{
while(_stack2Node != null_
{
if(_stack1Node.value == stack2Node.value)
{
IsRepeated = true;
}
}
_stack1Node=_stack1Node.nextNode;
}

return IsRepeated ;
}

- anup.h.nair December 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

from top/first node how you perform inorder traversal without having left and right addresses?.. root will have NULL as parent node and another random node

- Anonymous December 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Given that this is a BST, it will have left and right pointer with the addition of parent pointer.

- anup.h.nair December 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here you are comparing stack using nested loop. complexity will be O(n^2).

- visu January 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Going to the root, then doing a search for node2, and then deleting the common path between root->node1 path and root->node2 path is the obvious solution. What is the non obvious 'better' solution (if there is one)?

- underdog January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 4 vote

Step 1: find node with given value.
Step 2: now keep on moving both pointer till reach root.
Problem reduced to two linked list having common node ( Like Y structure)

- MI December 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

destination node address is not given, only value is given how you traverse from destination node to root?

- Anonymous December 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

From Given node, you can reach root...
then search value from the root.. you will get other node..

- MI December 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Answer you have given is correct. But this is right not the solution as you are not utilizing the nodes for random left and right nodes of particular node you are only concentrating on parent node.

- Anonumous December 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Going to the root, and then doing a search is the obvious solution. What is the non obvious 'better' solution?

- Underdog January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

if there is no root in the resultant path then your solution will be wrong

- Anonymous January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think people are mistaken about one thing. "We are not given the pointer to the destination node." Hence from the source node we have to traverse till the destination node.
In my point of view the one possible way we can do this is the method I specified in my comment.

- anup.h.nair January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct Node
{
int data;
struct Node *left;
struct Node *right;
struct Node *random;
struct Node *parent;
};
struct Node *NewNode(int data)
{
struct Node *temp=(struct Node *)malloc(sizeof(struct Node));
temp->data=data;
temp->left=NULL;
temp->right=NULL;
temp->parent=NULL;
temp->random=NULL;
return temp;
}

struct Node * Max(struct Node *first,struct Node *second,struct Node *third,int x)
{
if(!first && !second && !third)
return NULL;
if(!first && !second)
return third;
if(!first && !third)
return second;
if(!second && !third)
return first;
int a=first?first->data:-1;
int b=second?second->data:-1;
int c=third?third->data:-1;
struct Node *temp=NULL;
int val=0;
if(x==a)
return first;
else if(x==b)
return second;
else if(x==c)
return third;
if(a>b)
{
temp=first;
val=a;
}
else
{
temp=second;
val=b;
}
if(c>val)
{
temp=third;
val=c;
}
return temp;
}
struct Node * Min(struct Node *first,struct Node *second,struct Node *third,int x)
{
if(!first && !second && !third)
return NULL;
if(!first && !second)
return third;
if(!first && !third)
return second;
if(!second && !third)
return first;
int a=first?first->data:999;
int b=second?second->data:999;
int c=third?third->data:999;
struct Node *temp=NULL;
int val=0;
if(x==a)
return first;
else if(x==b)
return second;
else if(x==c)
return third;

if(a<b)
{
temp=first;
val=a;
}
else
{
temp=second;
val=b;
}
if(c<val)
{
temp=third;
val=c;
}
return temp;
}
bool Findpath(struct Node *node,int val)
{
if(!node)
return false;
if(node->data==val){
printf("%d",val);return true;}
if(node->data<val)
{
struct Node *temp=Max(node->right,node->random,node->parent,val);
if(Findpath(temp,val))
{
printf("%d",node->data);
return true;
}
}
else
{
struct Node *temp=Min(node->left,node->random,node->parent,val);
if(Findpath(temp,val))
{
printf("%d",node->data);
return true;
}
}
return false;
}

int main()
{
struct Node *node=NewNode(4);
node->left=NewNode(2);
node->left->left=NewNode(1);
node->left->right=NewNode(3);
node->right=NewNode(6);
node->right->left=NewNode(5);
node->right->right=NewNode(7);
node->right->right->right=NewNode(9);
node->right->right->right->left=NewNode(8);
node->left->parent=node;
node->right->parent=node;
node->left->left->parent=node->left;
node->left->right->parent=node->left;
node->right->left->parent=node->right;
node->right->right->parent=node->right;
node->right->right->right->parent=node->right->right;
node->right->right->right->left->parent=node->right->right->right;
node->random=node->left->right;
node->left->random=node->right;
node->left->left->random=node;
node->left->right->random=node->right->right;
node->right->random=node->right->right->right;
node->right->left->random=node->right->right->right->left;
node->right->right->random=node->right->right->right->left;
node->right->right->right->random=node->left->left;
node->right->right->right->left->random=node->left;
int val=8;
struct Node *find=node->left;
Findpath(find,val);
getchar();
return 0;
}

- Anonymous December 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

That is not correct. Suppose given pointer is to a node with value 100 (A node), and you are looking for node with value 75 (B Node). Suppose this was the input order in which the tree was constructed

80 75 101 100


starting with 100, you will reach 101 (C Node), at which point your algo would suggest that search in the right child tree of 101. Your search would fail.

- Underdog January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you please clarify the input..!!!!!!!! I think it is working fine.

- Anonymous January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I commented on wrong answer. See the next answer for where the comment should have been.

- Underdog January 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you put your algo here? Difficult to follow through the code without it. What is this random node business?

- underdog January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Each node in given tree (BST) has two pointers 1) parent node say p 2) random any other node say r.
So this forms another logical tree (with left and right pointers as p, r) where root is the current given node from which we want to find the path. Now we can traverse this new logical tree to find the target node with given value.
Obviously this assumes that newly formed structure with r and p pointers is forming a tree (ie, acyclic).

- jitter January 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

step1: compare the root and the given two value, move the root until two value are at different subtrees of the root ( now become root1)

step2: find the path of left node to the root1

step3: find the path of right node to the root1

- peng January 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the step 4: find the last sharing node of the two path, that's the answer ?

- oohtj January 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think step 1 has already found the last sharing node, which is root1. Step2 and step3 are trying to find the path.
Step4 is just merge these two paths.

- peng January 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Is there any use of the pointer that points to any node?

- DashDash January 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

1) if value == node.data then break
2) if(value < node.data )
a. if node is a right child of its parent and value is less than parent.data , move to parent
else
move to left subtree of the node

3) if(value > node.data)
a. if node is a left child of its parent and value is greater than parent.data, move to parent
else
move to right subtree of the data

4) continue until node is null or node.data == value

this would find a path whether the value exits in the subtrees of the node or anywhere else.

void findPath(Node node, int value) {
          
     if(node == null )
           throw new RtE();
             
     while(node != null) {
           
            System.out.println(node.data);
            if (node.data == value)
                     return;
          
             boolean isLeftChild = false, isRightChild = false;
          
             Node parent = node.parent;
             if(parent != null) {
                
                 if( parent.left == node)  
                           isLeftChild = true; 
                 else 
                          isRightChild  = true;  
              }
              if( value < node.data) {
                
                  if(isRightChild && value < parent.data)
                             node = parent;
                  else
                          node = node.left; 
               } else {
                   if(isLeftChild && value > parent.data )
                           node = parent;
                  else
                           node = node.right;
              }                         
    }

}

- learner January 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Consider a tree formed by this input - 110, 75, 101, 100. You are given a pointer to node with value 100, and are searching for 75. Your first condition, if(value < node.data ) is satisfied at node(100), and then within that if condition your code would move to left subtree of 100, and so miss finding 75.

- underdog January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Probably full of errors, but why wouldn't something like this work. Just traverse from the current node until you find the value or reach a null child.

ArrayList<Node> findPath(Node start, int toFind){
	ArrayList<Node> path = new ArrayList<Node>();
	Node curr = start;
	while(curr != null && curr.value != toFind){
		path.add(curr);
		if(curr.value > toFind && curr.parent().value > toFind){
			curr = curr.parent();
		} else if(curr.value < toFind && curr.parent() < toFind){
			curr = curr.parent();
		} else if(curr.value > toFind){
			curr = curr.left();
		} else{
			curr = curr.right();
		}
	}
	if(path.get(path.size()-1).value == toFind){
		return path;
	}
	return null;

- Anonymous January 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Start by adding the pointer to a stack. Add pointers of parents to the stack until you reach to root. You can then start at the root and search for the data value of the second node. If the top of the stack is the same as a node in the path, you pop. once you stop popping, you have found the most common ancestor (you must keep track of the last popped node to put it back on the stack). If you do not find a common ancestor but have found the initial node, your value is a descendant of it and you can continue adding pointers to your stack resulting in a stack with your path. O(logN).

- lodown414 January 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

First start moving from given node to till root. Once we get the root, this problem become like to get LCA. and the path we travel for that would be the "path from the given node (pointer), to the node with the given value".

- visu January 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Move the given node until we get root node or destination node. keep all the traversal node into the stack. if we get destination node break the loop and return all stack values else we reach to root then check both are not less than and not greater than from root. it means both are in different side.
if destination is greater than go right else go left and check the same condition. if both are same side then pop the value and move to that time until we get destination. In this case stack have all the node which we have to travel while going from given node to destination.

- visu January 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public ArrayList<Node> findPath(Node in, int val) {
ArrayList<Node> path = new ArrayList<Node>();

Node current = in;
while (current != null){
path.add(current);
if(val == current.getData()){
return path;
} else if (val < current.getData()) {
current = current.getLeftChild();
} else if (val > current.getData()) {
current = current.getRightChild();
}
}

if (current.getData() < val) {
ArrayList<Node> upperPath = new ArrayList<Node>();
current = in;

while(current != null){
upperPath.add(current);
if(val == current.getData()){
return path;
} else if (current == current.getParent().getRightChild()){
current = current.getParent();
} else {
current = current.getParent();
Node savedCurrent = current;

current = current.getRightChild();
ArrayList<Node> shortPath = new ArrayList<Node>();
while (current != null){
shortPath.add(current);
if(val == current.getData()){
upperPath.add(savedCurrent);
upperPath.addAll(shortPath);
return upperPath;
} else if (val < current.getData()) {
current = current.getLeftChild();
} else if (val > current.getData()) {
current = current.getRightChild();
}
}
current = savedCurrent;
}
}
} else {
ArrayList<Node> upperPath = new ArrayList<Node>();
current = in;

while(current != null){
upperPath.add(current);
if(val == current.getData()){
return path;
} else if (current == current.getParent().getLeftChild()){
current = current.getParent();
} else {
current = current.getParent();
Node savedCurrent = current;

current = current.getLeftChild();
ArrayList<Node> shortPath = new ArrayList<Node>();
while (current != null){
shortPath.add(current);
if(val == current.getData()){
upperPath.add(savedCurrent);
upperPath.addAll(shortPath);
return upperPath;
} else if (val < current.getData()) {
current = current.getLeftChild();
} else if (val > current.getData()) {
current = current.getRightChild();
}
}
current = savedCurrent;
}
}
}
return null;

}

- Siddharth January 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public ArrayList<Node> findPath(Node in, int val) {
        ArrayList<Node> path = new ArrayList<Node>();
        
        Node current = in;
        while (current != null){
            path.add(current);
            if(val == current.getData()){
                return path;
            } else if (val < current.getData()) {
                current = current.getLeftChild();
            } else if (val > current.getData()) {
                current = current.getRightChild();
            }
        }
        
        if (current.getData() < val) {
            ArrayList<Node> upperPath = new ArrayList<Node>();
            current = in;

            while(current != null){
                upperPath.add(current);
                if(val == current.getData()){
                    return path;
                } else if (current == current.getParent().getRightChild()){
                    current = current.getParent();    
                } else {
                    current = current.getParent();
                    Node savedCurrent = current;

                    current = current.getRightChild();
                    ArrayList<Node> shortPath = new ArrayList<Node>();
                    while (current != null){
                        shortPath.add(current);
                        if(val == current.getData()){
                            upperPath.add(savedCurrent);
                            upperPath.addAll(shortPath);
                            return upperPath;
                        } else if (val < current.getData()) {
                            current = current.getLeftChild();
                        } else if (val > current.getData()) {
                            current = current.getRightChild();
                        }
                    }
                    current = savedCurrent;
                }
            }    
        } else {
            ArrayList<Node> upperPath = new ArrayList<Node>();
            current = in;

            while(current != null){
                upperPath.add(current);
                if(val == current.getData()){
                    return path;
                } else if (current == current.getParent().getLeftChild()){
                    current = current.getParent();    
                } else {
                    current = current.getParent();
                    Node savedCurrent = current;

                    current = current.getLeftChild();
                    ArrayList<Node> shortPath = new ArrayList<Node>();
                    while (current != null){
                        shortPath.add(current);
                        if(val == current.getData()){
                            upperPath.add(savedCurrent);
                            upperPath.addAll(shortPath);
                            return upperPath;
                        } else if (val < current.getData()) {
                            current = current.getLeftChild();
                        } else if (val > current.getData()) {
                            current = current.getRightChild();
                        }
                    }
                    current = savedCurrent;
                }
            }    
        }
        return null;
        
    }

- Siddharth January 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I find that we can improve the algorithm still with no additional space required and lesser no of node accesses.

- traverse from the "given node" towards the root
- at every node (cur_node) on the path, check for the following :

if (current value matches the given value) then path is found
else (if the to_find value is in between current value and parent value then to_find value is either in other subtree of the parent or directly under the "given node")

once we know the subtree in which to_find value is present, we can traverse the path conduction a binary search

for to_find value to be in between current value and parent value either of the following 2 conditions must be true

- current value > parent value and to_find value > parent value and to_find value < current value
- current value < parent value and to_find value < parent value and to_find value > current value

This algo should work in O(logN) time without any extra space

Do let me know if you see any flaws/deviating cases in the logic

- Srikanth January 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

not working man.... consider example to find 25, current at 30 in one 20 in another
20 30
| and |
v v
30 20

- the best solution February 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

The question was confusingly stated. It should have been
There's a BST, with each node having a parent pointer. Given that BST, a pointer to a node (any node), and a value, find the path from the given node (pointer) to the node with the given value.


Assuming the tree is balanced, you can do it in O(log n) time.
Find the lowest common ancestor for the two nodes using the parent pointers. Then it's just a matter of unioning the path from the two nodes to the lowest common ancestor.
Or even better.
If P1 is the path from A to the root and P2 is the path from B to the root. Path from A to B is (P1 - P2) U (P2 - P1), where the subtraction operation is performed on the edges.

- Jagat January 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

*the second one is just the value not the reference to the node..."

- Anuj Agrawal January 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your are not given a pointer to the second node; you are only given a value to search for. How are you going to find the common ancestor?

- underdog January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can't we do a DFS and and get the path....

- Anuj Agrawal January 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can. Is it better than 'walk up to the root and then a binary search for the value. Delete the common path between the path to root from node1 and from root to node2'.

It is not. If you do DFS, you are not even taking advantage of BST properties. A DFS will take O(E) time. E for BST is of the order N.

Walking up to the root, and doing a binary search would be O(log(N)) time. At worst you will be doing two walks; one up to the root, and one from root to the node2.

- underdog January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

//1) traverse to the root node(top/first node) of BST and calculate the length.
//c#
public int path(Node _node)
{
if (_node == rootNode) { return 0; }
return 1 + path(Node _node.parentNode);
}

//2) traverse from the root node(top/first node) of BST to the destination node using InOrder and calculate the length.
//c#
public int InOrder(Node _node,Node _destinationNode)
{
if (_node == _destinationNode) return 0;
return 1 + InOrder(_node.leftNode, _destinationNode);
return 1 + InOrder(_node.rightNode, _destinationNode);
}

- Anonymous December 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

what time complexity for evulating a postfix expression ?

- caliber December 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Move the given node until we get root node or destination node. keep all the traversal node into the stack. if we get destination node break the loop and return all stack values else we reach to root then check both are not less than and not greater than from root. it means both are in different side.
if destination is greater than go right else go left and check the same condition. if both are same side then pop the value and move to that time until we get destination. In this case stack have all the node which we have to travel while going from given node to destination.

- visu January 07, 2013 | Flag


Add a Comment
Name:

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

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More