Amazon Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: In-Person
I think your logic is true; however, every node has 0 or more children nodes. So that, we should be careful about memory allocation. the interviewer give me an example tree:
10
3 7 9
2 1 4 5 6 & 3 4 6
2 4 5
(&) indicates no children
Also, we cannot be sure about the tree is balanced or not.
You do BFS traveral of the tree, with a modified queue which holds tuples of the form (node, copied-parent). When a tuple is de-queued from the queue, we create a new node which is a copy of the node in the tuple, and add it as a child of the copied-parent from the tuple.
For each child of the node, we enqueue a tuple (child, new-node).
def tree_copy(root):
q=new queue()
q.enqueue((root, None))
new_root=None
while (!q.empty()):
node, new_par=q.dequeue()
new_node=new Node()
new_node.val=node.val
if (!new_root):
new_root=new_node
if new_par:
new_par.children.append(new_node)
foreach child_node in node.children:
q.enqueue((child, new_node))
you can do it using two queues.
TreeNode copyTree(TreeNode root){
if(root == null)
return null;
Queue<TreeNode> q1 = new LinkedList<TreeNode>;
Queue<TreeNode> q2 = new LinkedList<TreeNode>;
int level=1;
TreeNode new_root = new TreeNode(root);
TreeNode temp_root = new_root;
TreeNode temp = new TreeNode();
TreeNode marker = new TreeNode("#");
q1.enqueue(root);
q1.enqueue(marker);
q2.enqueue(root.left);
q2.enqueue(root.right);
while(!q1.isEmpty()){
temp = q1.enqueue();
if(temp == marker){
q1.enqueue(temp);
}
else{
q1.enqueue(temp.left);
q1.enqueue(temp.right);
if(level!=1){
q2.enqueue(temp.left);
q2.enqueue(temp.right);
}
temp_root.left = new TreeNode(q2.dequeue());
temp._root.right = new TreeNode(q2.dequeue());
level++
}
}
return new_root;
}
Simple code using two queues:
Node clone(Node root) {
if(null == root)
return null;
Queue<Node> q1 = new LinkedList<Node>();
q1.add(root);
Queue<Node> q2 = new LinkedList<Node>();
Node root2 = new Node(root.data);
q2.add(root2);
Node n, fresh;
while(!q1.isEmpty()) {
n=q1.remove();
fresh = q2.remove();
if(null != n.left) {
q1.add(n.left);
fresh.left = new Node(n.left.data);
q2.add(fresh.left);
}
if(null != n.right) {
q1.add(n.right);
fresh.right= new Node(n.right.data);
q2.add(fresh.right);
}
}
return root2;
}
i would probably do the level order traversing.store the values in a list (preserve order).
Then build the new copied tree from that.since left_child=2*i+1 and right is 2*i+2 assuming root node is at index i.repeat this until no nodes..Add zero to list when level order traversal to indicate that its null..
The tree has unlimited number of children. If the tree is unbalanced, there will be quite a lot of zeros added to the list when doing level order traversal.
I think two queues will be a good solution. Do copy right when traversing the old tree. After generating a new node in the new tree, the old nodes will be removed from the head of the queue. It may not exceed the memory budget.
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.tree.TreeNode;
/**
* copy tree with unlimited number of children with breadth fist search...
*/
public class CopyTreeBFSeg {
/**
* @param args
*/
int data;
CopyTreeBFSeg leftChild, rightChild;
public CopyTreeBFSeg(int data){
this.data = data;
leftChild = null;
rightChild = null;
}
public CopyTreeBFSeg(){}
public CopyTreeBFSeg(CopyTreeBFSeg node){
this.data = node.data;
this.leftChild = null;
this.rightChild = null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CopyTreeBFSeg obj = new CopyTreeBFSeg();
CopyTreeBFSeg root = new CopyTreeBFSeg(5);
CopyTreeBFSeg lc = new CopyTreeBFSeg(6);
CopyTreeBFSeg rc = new CopyTreeBFSeg(7);
root.leftChild = lc;
root.rightChild = rc;
CopyTreeBFSeg newRoot = obj.copyTree(root);
System.out.println("new tree: ");
System.out.println(newRoot.data + " ");
System.out.println(newRoot.leftChild.data + " ");
System.out.println(newRoot.rightChild.data + " ");
}
public CopyTreeBFSeg copyTree(CopyTreeBFSeg root){
Queue<CopyTreeBFSeg> nodeQueue = new LinkedList<CopyTreeBFSeg>();
CopyTreeBFSeg newRoot=null;
CopyTreeBFSeg newNode=null, tempNode = null;
CopyTreeBFSeg markerNode= new CopyTreeBFSeg(0);
if(root==null){
return root; //nothing to copy
}
nodeQueue.add(root);
CopyTreeBFSeg newTreeNode = null;
CopyTreeBFSeg parentNode = null;
int lc=0,rc=0;
while(!nodeQueue.isEmpty()){
if(parentNode==null){
parentNode = newTreeNode;
}
tempNode = nodeQueue.remove();
if((tempNode.data==0)&&(lc==0)){
lc=1;
rc=0;
parentNode=parentNode.leftChild;
continue;
}
else if((tempNode.data==0)&&(rc==0)){
lc=0;
rc=1;
parentNode=parentNode.leftChild;
continue;
}
if((parentNode!=null)&&(tempNode.data!=0)){
if(parentNode.leftChild== null){
parentNode.leftChild = tempNode;
}
else{
parentNode.rightChild = tempNode;
}
}
if(tempNode.leftChild!=null){
nodeQueue.add(tempNode.leftChild);
}
if(tempNode.rightChild!=null){
nodeQueue.add(tempNode.rightChild);
nodeQueue.add(markerNode);
}
newTreeNode = new CopyTreeBFSeg(tempNode);
if(newRoot==null){
newRoot = newTreeNode;
}
}
return newRoot;
}
}
Something along these lines? Though obviously if the "unlimited number" is extremely large, there'd be memory issues...
- Anonymous December 04, 2012