Amazon Interview Question
Software Engineer / DevelopersTeam: Kindle
Country: India
this was not east it was hidden bug. the answer to the question lies in the fact that the call t.nary_list.iterator() creates NEW iterator, so each recursive call creates new iterator meaning you start again from the start of the list and the recursion never stop.
The solution is to define an Iterator veriable before the recursive call:
void display(NaryTreeNode t)
{
Iterator itr = t.nary_list.iterator();
if(!(itr.hasNext())) //If the node does not have any children, enter.
{
System.out.println("No more childs of this node");
System.out.println("Value is: " + t.data);
return;
}
while(itr.hasNext())
{
display((NaryTreeNode )itr.next()) ; //Recursive Call
}
System.out.println("Jumping One Level up");
System.out.println(t.data);
}
if i correctly understand your question this is nothing but traversal of the tree
u can use either BFS or DFS
lets say its n- ary tree
the structure will be something like
{struct tree {
int data ;
struct tree *children[n]; //array of pointers to n children (they may be nulls also )
}
now use a queue for BFS
while dequeuing a node in the queue
traverse all the nodes like
for(i=0;i<n;i++)
if(!current ->children[i])
enqueue(current ->children[i])
}
hope its clear ...
package com.narray;
public class NaryTree {
NaryTreeNode root;
public NaryTree(NaryTreeNode root) {
this.root = root;
}
public static void main(String[] args) {
NaryTreeNode root = new NaryTreeNode(100);
NaryTree tree = new NaryTree(root);
NaryTreeNode childroot1 = new NaryTreeNode(20);
NaryTreeNode childroot2 = new NaryTreeNode(30);
NaryTreeNode childroot3 = new NaryTreeNode(40);
NaryTreeNode childroot4 = new NaryTreeNode(50);
root.add(childroot1);
root.add(childroot2);
root.add(childroot3);
root.add(childroot4);
NaryTreeNode child1ChildRoot1 = new NaryTreeNode(80);
NaryTreeNode child2ChildRoot1 = new NaryTreeNode(90);
childroot1.add(child1ChildRoot1);
childroot1.add(child2ChildRoot1);
NaryTreeNode child1ChildRoot2 = new NaryTreeNode(110);
childroot2.add(child1ChildRoot2);
NaryTreeNode child1ChildRoot3 = new NaryTreeNode(120);
NaryTreeNode child2ChildRoot3 = new NaryTreeNode(130);
childroot3.add(child1ChildRoot3);
childroot3.add(child2ChildRoot3);
tree.display(root);
}
private void display(NaryTreeNode node) {
if(node.getChildren().size() > 0) {
for(int i = 0 ; i < node.getChildren().size() ; i++) {
display((NaryTreeNode)node.get(i));
}
System.out.println(node.getData());
} else {
System.out.println(node.getData());
}
}
}
package com.narray;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class NaryTreeNode implements List{
int data;
List<NaryTreeNode> children;
public NaryTreeNode(int data) {
this.data = data;
children = new ArrayList<NaryTreeNode>();
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public List<NaryTreeNode> getChildren() {
return children;
}
public void setChildren(List<NaryTreeNode> children) {
this.children = children;
}
@Override
public boolean add(Object narayTreeNode) {
children.add((NaryTreeNode) narayTreeNode);
return true;
}
@Override
public void add(int arg0, Object arg1) {
// TODO Auto-generated method stub
}
@Override
public boolean addAll(Collection arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean addAll(int arg0, Collection arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public void clear() {
// TODO Auto-generated method stub
}
@Override
public boolean contains(Object arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean containsAll(Collection arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object get(int index) {
// TODO Auto-generated method stub
return children.get(index);
}
@Override
public int indexOf(Object arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
@Override
public Iterator iterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public int lastIndexOf(Object arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public ListIterator listIterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public ListIterator listIterator(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean remove(Object arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object remove(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean removeAll(Collection arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean retainAll(Collection arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object set(int arg0, Object arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int size() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List subList(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object[] toArray() {
// TODO Auto-generated method stub
return null;
}
@Override
public Object[] toArray(Object[] arg0) {
// TODO Auto-generated method stub
return null;
}
}
I hav'nt implements all the method for NarayTreeNode.
Can someone help.
For the start i have just used a tree with root node having only three children.
Here is the code in java:
Looks like the iterator is not functioning properly so i get stuct in the while loop in the display function. :(
import java.util.*;
import java.io.*;
import java.util.List;
public class NaryTreeNode {
int data;
List <NaryTreeNode> nary_list = new ArrayList<NaryTreeNode>();
}
public class NaryTree
{
void display(NaryTreeNode t)
{
if(!(t.nary_list.iterator().hasNext())) //If the node does not have any children, enter.
{
System.out.println("No more childs of this node");
System.out.println("Value is: " + t.data);
return;
}
while(t.nary_list.iterator().hasNext())
{
display(t.nary_list.iterator().next()) ; //Recursive Call
}
System.out.println("Jumping One Level up");
System.out.println(t.data);
}
public static void main(String args[]){
NaryTree t1 = new NaryTree();
NaryTreeNode root = new NaryTreeNode();
root.data = 100;
NaryTreeNode lev_11 = new NaryTreeNode(); lev_11.data=90;
NaryTreeNode lev_12 = new NaryTreeNode(); lev_12.data=50;
NaryTreeNode lev_13 = new NaryTreeNode(); lev_13.data=70;
//Adding all the child nodes to a list
List<NaryTreeNode> temp = new ArrayList<NaryTreeNode>();
temp.add(lev_11);
temp.add(lev_12);
temp.add(lev_13);
//Adding the list as a node to root so that we now have root with three children
root.nary_list.addAll(temp);
//Call the display function to traverse
t1.display(root);
}
}
Output:
No more childs of this node
Value is: 90
No more childs of this node
Value is: 90
No more childs of this node
Value is: 90
.
.
.
.
Guys check out my solution.. any input is welcome.
class Node
{
int data;
ArrayList<Node> children;
Public Node(int value)
{
data = value;
children = new Arraylist<Node>();
}
}
Public void traverse(Node root)
{
if(root == NULL)
return;
for(Node child:root.children)
{
traverse(child);
}
System.out.Println(root.data + " ");
}
// this is a recursive question
typedef struct Node {
T data;
Node *left, *right;
}
// assuming the Nary operates like any Tree then the following would be used to output values
// in C++
template <typename T>
void Nary<T>::displayAll(Node *leaf)
{
if(leaf != 0) // i.e., NULL
{
displayAll(leaf->left);
std::cout << leaf->data << std::endl;
displayAll(leaf->right);
}
}
This is old, but it might be of help to few people.
public class NaryTree {
public static void printChildren(FolderFile root){
if(root==null)return;
System.out.println(root.name);
for(Iterator newfile=root.children.iterator();newfile.hasNext();){
FolderFile child = (FolderFile)newfile.next();
printChildren(child);
}
}
public static void main(String args []){
NaryTree obj = new NaryTree();
FolderFile root = new FolderFile("folder1");
Set<FolderFile> children = root.children;
FolderFile child1 = new FolderFile("child1");
FolderFile child2 = new FolderFile("child2");
FolderFile child3 = new FolderFile("child3");
children.add(child1);
children.add(child2);
children.add(child3);
Set<FolderFile> subchild = child1.children;
FolderFile subchild1 = new FolderFile("subchild1");
FolderFile subchild2 = new FolderFile("subchild2");
FolderFile subchild3 = new FolderFile("subchild3");
subchild.add(subchild1);
subchild.add(subchild2);
subchild.add(subchild3);
printChildren(root);
}
}
class FolderFile{
String name;
Set<FolderFile> children;
public FolderFile(String name){
this.name = name;
this.children = new HashSet<FolderFile>();
}
}
Here is the solution, however I need to refine the traversal to DFS or BFS
- chaos October 06, 2012