Amazon Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




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

This could be done with a level order traversal (or bfs tree traversal). if the interviewer didn't want that you could simulate a threaded bst using what is called Morris Traversal.

- Bob September 19, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here is the code using bfs:

void Delete (Tree *root) {
    if (!root) return;
    Queue <Tree *> q;
    q.enQ(root);
    while(!q.isEmpty()) {
        Tree * cur = q.deQ();
        if (cur->left) q.enQ(cur->left);
        if (cur->right) q.deQ(cur->right);
        delete cur;
    }
}

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

Well, here you are pushing nodes into the queue, and popping them off the queue. How does that delete the tree? It remains just as it is.

- Cupidvogel October 04, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@cupid: You missed the delete cur line?

- Anonymous October 08, 2012 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

If the question is to be coded in java, can we say that we can remove the reference to the tree and garbage collector will take care of it?

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

@yinyan - In java, the memory management is automatic (i.e. JVM is responsible for it and not the application developers). So you're idea of removing only the reference of the root of the tree would eventually free all the memory. However, for the sake of understanding this question, the java-equivalent would be: How could you remove all the parent child references in a binary-tree without recursive algorithm!

- buckCherry January 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
3
of 3 vote

void DeleteTree(Node* root)
{
	std::stack<Node*> nodes;
	nodes.push( root);
	while( ! nodes.empty())
	{
		Node* topNode = nodes.top();
		nodes.pop();

		if ( topNode->left )
			nodes.push(topNode->left);

		if ( topNode->right )
			nodes.push(topNode->right);

		delete topNode;
	}
}

- raj September 19, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Apart from not handling the case when root is null, this looks good!

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

One thing to be aware of here, is that using a stack makes this a depth first search. Traditionally a BFS traversal uses a Queue. In an interview you might get dinged for not understanding the nuance, though this solution will work fine (level order depth first search) however it is not the classic approach.

- Timmy September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Timmy: What in the world are you talking about?

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

Post order traversal.

- noobie September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

you don't have to use any storage actually. It's a postorder traversal that eliminates the leaves.

void delete_tree_nonrecursive(Node** root)
{
    if (!root || !(*root) ) return;
    Node *node = *root; // start from the root
    while(1)
    {
        if (node->left)
            node = node->left; //explore left
        else if (node->right)
            node = node->right; // explore right
        else if (node->parent) // back up 
        {
            Node *leaf = node; // save pointer to leaf
            node = node->parent; // move up to parent
            if (node->left == leaf)
                node->left = 0; // disconnect leaf
            else
                node->right = 0; // disconnect leaf
            delete leaf; // delete leaf
        }
        else
        {            
            delete node; // delete root
	    *root = 0; // change the pointer to root node to NULL
            break; //stop
        }
    }
}

- oos September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

here, storing parent node takes O(n) additional space.
Similar to usage of stack for BFS. -- O(N)

- mrb September 23, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@mrb: there's no storage of parents here, in fact you don't store anytthing [except for a local swap operation].

The algorithm just navigates in the tree, exploring towards children, deleting leaves and backing up when a leaf has been deleted.

- oos September 24, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

what is node->parent ????

- okaysh September 25, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If i am understanding the node structure for the tree node is as

struct node
{
   struct node* left;
   struct node* right;
   struct node* parent;
   int data;
};

So basically we are using extra space already for each node.
Correct me if i am wrong?

- NewCoder October 08, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is adding extra nod val per node ( parent). Then how you can say its not using any extra storage. queue solution is better.

- vm October 08, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

check this O(1) implementation ...

{
struct node * getleftmost(struct node * somenode)
{
while(somenode->left)
somenode=somenode->left;
return somenode
}





void delete(struct node *root)
{
if(root==NULL)
return ;

while(root)
{
temp=root;
if(root->left){
if(root->right)
getleftmost(root)->left=root->right;
else
root=root->left;
}
else if (root->right)
root=root->right;
else
root=NULL;
free(temp);
}

}

- sreeram September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is a brilliant solution if you're trying to avoid using parent or a stack. However, it's not O(1). In fact it's pretty damn expensive since you're calling getleftmost() so often. Haven't tried to compute how much exactly but it's gotta be expensive with all the right subtrees being slapped on to the left most leaf.

- fizzybuzzer September 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

i do agree...its costly ...i actually meant o(1) space implementation ..

there is no point if u try to use a stack or queue ...
because recursion anyway takes O(n) space on the stack

just check this function ...which converts the tree to list

{
struct node * converttolist(struct node *root)
{
if(root ==NULL)
return NULL;

struct node *realhead=root;
struct node *head=root;
while(head->left)
head=head->left;

while(root)
{
if(root->right){
root=root->right;
while(root){
head->left=root;
head=head->left;
root=root->left);
}
}
root=root->left;
}
return realhead;
}

}


now that i got a list i can just traverse the list to delete tree

- sreeram September 25, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

sreeram, your original delete treee w/o recursion is amazing. wow!!!

- vm October 08, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice soln !

- amit December 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Non recursive inorder traversal ....beacuse it will start from the leaves..

- kavita.123green September 21, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void deleteTree(TREE* head)
{
	if(head==NULL)
		return ;

	deleteTree(head->left);
	deleteTree(head->right);
	free(head);
}

- okaysh September 25, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void delete(Node root){
	Stack<Node> S = new Stack<Node>();
	Node current = root;
	while (current.leftChild != null){
		S.push(current);
		current = current.leftChild;
		current.Visited = false;
	}
	while (!S.isEmpty()){
		current = S.pop();
		if (!current.Visited){
			S.push(current);
			current.Visited = true;
			current = current.right;
			while (current.leftChild != null){
				S.push(current);
				current.Visited = false;
				current = current.leftChild;
			}
		}else{
			delete(current);
		}
	}
	return;
}

- Arian Hosseinzadeh June 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void DeleteTree(Node root){
deleteTree(root);
root = null;
}

void deleteTree(){
if(root == null) return;

Queue<Node> q = new LinkedList<Node>();

//do level order traversal

q.add(root);

while(!q.isEmpty()){
Node node = q.poll();

if(node.left != null){
 q.add(node.left);
}//if

if(node.right != null){
q.add(node.right);
}//if

}//while

}

- akhil11choudhari October 28, 2016 | Flag Reply


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