Amazon Interview Question for Software Engineer / Developers






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

I am not quite understand the answer above but based on the same idea of using just a O(1) space the solution could be following:
1)[Merge listst]Create list B this way: for each NodeA in A create a NodeB in B , copy NEXT ptr to NodeB: NodeB{NEXT} = NodeA{NEXT} and change NEXT ptr in NodeA to this newly created node in B: NodeA{NEXT}=NodeB;
2) go through the list A (NB: you have to jump through the nodes of B!) and set NEXTRND ptr in next B nodes to the next ptrs after next_random nodes: NodeA{NEXT}{NEXTRND}=NodeA{NEXTRNF}{NEXT};
After that all NEXTRND nodes in list B will be pointing to correct nodes in B;
3) [Un-merge]. For each node in A and in NEXT node B set correct NEXT ptrs:
node=headA;
while(node){tmp = node{NEXT}; node{NEXT}=tmp?tmp{NEXT}:NULL; node=tmp;}
After this process all {NEXT} nodes in both lists A and B will be correct

- celicom December 20, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

awesome...! thanks a lot :)

- rhino December 20, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

best solution!

- alfa December 25, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

excellent solution.... superb....thanks :)

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

good thinking celicom!

- blrbuddy March 25, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

superb solution celicom..

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

It seems that nobody replies. Just throw my idea on the table.

Assume the node has two pointers, one is called next, the other is called randomnext.

Go through the list by using "next", create a hashmap A with (Node -> serial number(1,2,3,...)). Go through the list again to create another hashmap(list) B with (serial number -> the randomnext's serial number) by the aid of A.

duplicate the list by using "next" and create the hasmap C with (serial number -> Node). Go through the newly created list again, use the current position (serial number) to check the hashmap(list) B to find out the position of the randomnext's serial number. Use the hashmap C to find out the node. Link the randomnext node.

- majun8cn September 21, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Quick question, when we create the duplicate list does it need to have the pointer to the random node as well ?

- abhimanipal April 09, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

yeah of course...

- Vishwaatma June 28, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think only one hash map is enough. During first traversal on list, create a haspmap with oldpointer to new pointer. Now traverse the original list again and and link the newrandom pointer.

- Erik September 22, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Why do you even need a single hash map... As we move through the original list, node by node, simultaneously create the second list as well.
Then connect the random pointers as well

What do you think ?

- abhimanipal April 09, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is the approach with single traversal and single hashtable:

class Node
    {
        public int data;
        public Node Next = null;
        public Node RandomNext = null;
        private Node() { }
        public Node(int d)
        {
            data = d;
        }
    }

public static Node CopyList(Node head)
        {
            Node newHead = null;
            Hashtable ht = new Hashtable();
            Node newNode;
            Node currentNode = null;
            while (head != null)
            {
                int hcode=head.GetHashCode();
             if(!ht.ContainsKey(hcode)   )
             {
                 newNode=new Node(head.data);
                 ht.Add(hcode, newNode);
             }
             else
             {
                 newNode=(Node)ht[hcode];
             }
             if (newHead == null)
             {
                 newHead = newNode;
                 currentNode = newNode;
             }
             else
             {
                 currentNode.Next = newNode;
                 currentNode = currentNode.Next;
             }
             if (head.RandomNext != null)
             {
                 hcode=head.RandomNext.GetHashCode();
                 if (!ht.ContainsKey(hcode))
                 {
                     newNode = new Node(head.RandomNext.data);
                     ht.Add(hcode, newNode);
                 }
                 else
                 {
                     newNode = (Node)ht[hcode];
                 }
                 currentNode.RandomNext = newNode;
             }
             head = head.Next;
            }
            return newHead;
        }

- B September 26, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

B: add a couple of lines explaining the flow of your algo/logic. :-)

- abe September 28, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

why can't you understand the code? it so obvious you fucking retard

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

Anonymous on October 08, 2009: B'coz we're not as retarded as you are. Your moron !
If your understand why d0nt you explain, you scruffy crappy idiot.

- Anonymous October 09, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

abe fucked

- ass September 21, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

are you sure we know which pointer points to next node and which points to random node? What if they're just two pointers and you cant tell who is pointing the next node and the random node.

- Anonymous November 04, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

There is no need to create hashmap. let the two lists be A and B.

while copying a node nb in B from node na in A, change the random pointer of na to na->rand^nb. Also copy the original data and random pointer of na in node nb.

After copying all the nodes, again traverse two lists and this time,
nb->rand = nb->rand^na->rand = node in list b to which nb should point.

A third pass will be needed to restore the original random pointers in A.
na->rand = na->rand^nb^nb = na->rand;

- Anon November 11, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

can u pls explain how u perform ^ operation between 2 nodes na and nb...?
if some1 can explain that.. then i think the probelem will be solved completely...

- rhino December 18, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Don't bother. The solution given by "Anon on November 11,2009" is wrong.

Need not even go into analysis (although I have done that). Take a simple example as below and it would fail.

Lets say the original list has two nodes:
A (address - 001) and B(address - 010)
Also consider
A.rand = 010
B.rand = 010

Now let's create the other nodes, let's call them C and D.
C (address 111)
D (Address 110)

Work with this example and the solution given doesn't work.

- Calista December 28, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

typo: NodeA{NEXTRNF}{NEXT}; -> NodeA{NEXTRND}{NEXT};
NB: NodeA{NEXT} - is a node in B list!

- celicom December 20, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

cool solution.

struct Node
{
    int data;
    struct Node* next;
    struct Node *rand;
};

Here is the same along the lines mentioned by celicom. Kudos to celicom.

// To give the big picture :
// when you form the daisy chain with node from first
// list to a node in second list, effectively you are
// establshing a 1:1 correlation between Node i in list1
// and node i in List2. So instead of using a hash table
// you "remember" it this way.

void CopyLinkedList(Node *pSrc, Node **ppDst)
{
	// daisy chain link
	for(Node *pCur = pSrc; pCur; )
	{
		Node *pTmp = new Node();
                // handle error. Undo the links
                // that were done so far, delete 
                // allocated memory and return.
		pTmp->data = pCur->data;
		pTmp->next = pCur->next;
		pCur->next = pTmp;
		pCur=pCur->next->next;
	}

	// store the head of the new link
	*ppDst = pSrc->next;

	// update the rand pointers of dst
	for(Node *pCur = pSrc; pCur; )
	{
		pCur->next->rand = (pCur->rand)?pCur->rand->next:null;
		pCur = pCur->next->next;
	}

	// un-daisy chain links
	for(Node *pCur = pSrc; pCur; )
	{
		Node *pNextSrc = pCur->next->next;
		pCur->next->next = (pNextSrc)?pNextSrc->next:null;
		pCur->next = pNextSrc;
		pCur = pNextSrc;
	}
}

- Calista December 25, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

though looks complex initially its simple one....

A: Original List
B: Copy List

First pass:
make a copy of linked list using next ptr of A. With this..
B will have every next ptr perfectly placed.
While copying each node, make nodeA->next = nodeB; and NodeB->random=nodeA;

Second Pass:
Traverse B and make nodeB->random = nodeB->random->random->next;

Done; Correct me if something is wrong.

- master December 30, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

forgot to make sure List A same as given Original List.

Second Pass: (please check for null ptr wherever necessary)
temp = nodeB->random;
Traverse B and make nodeB->random = nodeB->random->random->next;
temp->random->next = temp->random->next->next->random;

// any comments?

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

sorry....above solution does not take care of keeping original list as it is.. any thoughts?

- master December 30, 2009 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

you will need some kind of hash map to remember where ->random points. Also ->random in list A and B are different.

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

This is an O(n) solution , but yeah it takes 2 hash map.

First, traverse through list A , while traversing store in hash map_A the <address_old_list_node, index> and copy this node to the new linked list.

when creating new linked list , store the index and the address_new in another hash map_B <index, address_new_malloced_node>.

So at the end of the pass one, we have two hash maps and two list. New list does not have the random pointers.

In second pass, traverse through the first list for every random pointer address get the index of the pointer from map_A and get the corresponding new address for that index from map_B and point the random pointer of the list B to this address.

So totally in two pass we have the linked list.

- girish kathalagiri February 28, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Instead of two maps, one map is enough. Which maps Old list address to new list address. Instead of having intermediate index. One can have a direct mapping of addresses

- girish kathalagiri March 01, 2010 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Why not this:

Random&Next(CurrentA, CurrentB)
{
CurrentB.next = CurrentA.next;
CurrentB.value = CurrentA.value;
CurrentB.random = CurrentA.random;
Random&Next(CurrentA.Random, CurrentB.Random);
Random&Next(CurrentA.next, CurrentB.next);
}

- Anonymous March 20, 2010 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Go over the original list following next links and create the new list. (new list will contain only the next pointers for now) Meanwhile put the new nodes in a hash map. (the key is the address of the old node and the value is the address of new node)
2. In the second scan, go over both lists in parallel. For each arbitrary pointer in the original list, fetch the address of corresponding node from hashmap.

- anon1234567890 April 06, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ya, you have to do it without extra space

- @Anon April 07, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You already use extra space when you create new list

- Michal April 07, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

doing a second scan is not always acceptable because the list can be huge... the same logic can be used and we can achieve the desired output in single pass...

1. while traversing list1 and making a copy of list1, we will put the following info in hashmap
a) ptr1->ptr2 b)ptr1->next,ptr2->next c) ptr1->arbitrary, ptr2->arbitrary

before creating a new node we will first do a search in hashmap... if it is not there then only we will create new node and set the next,prev and arbitrary pointers and insert above 3 pairs to hashmap.
If the new node in list1 is already present in the node1 then make the corresponding linking...

- swathi June 01, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

it's a graph so, you can copy it DFS style marking the nodes with a 'visited' marker. Complexity O(|V|+|E|)

- 1lik3b1gbuttz April 07, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can you elaborate more on your graph method?

- kanishka.subramanian April 09, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Following method should work with O(n) complexity and no extra space.

Original List a1->b1->c1->d1->e1

Let Random pointers of original list be a1->c1, b1->d1, c1->a1, d1->c1, e1->e1

Start traversing the original list, while traversing create new nodes as well.
When u do that, do one more thing, point the random pointer of the original node to the newly created node, and
point the random pointer of this newly created node to the node which was pointed by random pointer of the original node.

After performing the above action

Original List a1->b1->c1->d1->e1

Random pointers of original list
a1->a2, b1->b2, c1->c2, d1->d2, e1->e1

New list a2->b2->c2->d2->e2

Random pointers of new list:
a2->c1, b2->d1, c2->a1, d2->c1, e2->e1

Now traverse both the lists again simultaneously

since a1->a2, a2->c1 and c1->c2 (perform actions on random pointers)=> a1->c1, a2->c2
b1->b2, b2->d1 and d1->d2 (perform actions on random pointers)=> b1->d1, b2->d2
c1->c2, c2->a1 and a1->a1 (perform actions on random pointers)=> c1->a1, c2->a2

thus new similar list is formed

- Ishant April 11, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Awesome :)

- Akash April 13, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This doesn't work. What will happen in just next step?
d1->d2, d2->c1, c1->a1 (c1's random in now pointing to a1. So how to go ahead?)

- aa April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

could anyone explain the question? how does it mean?

- Anonymous April 12, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

tech-queries.blogspot.com/ 2011/04/copy-linked-list-with-next-and-random.html

- Anonymous April 15, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

create the copy of 1 and insert between 1 & 2, create the copy of 2 and insert between 2 & 3.. continue in this fashion add the copy of N to Nth node

Now copy the arbitrary link in this fashion Original->next->arbitrary = Original->arbitrary->next; TRAVERSE TWO NODES;

This works because original->next is nothing but copy of original and Original->arbitrary->next is nothing but copy of arbitrary.

now restore the Original and copy linked lists in this fashion in a single loop.
Original->next = Original->next->next;
copy->next = copy->next->next;

Make sure that last element of original->next is NULL.

- Chandan Prakash April 17, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I guess this should work.Nice!

- ashay.ut April 17, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Very nice :D :D

- Niraj April 28, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

we need to take care of adjusting the prev pointers correctly...

- swathi June 01, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct node *clone(struct node *head)
{
HasMap h=new HashMap();

for(current1=head;current1;current=current->next)
{
temp=malloc(sizeof(struct node));
h.put(current,temp);

- brahmasani99 May 24, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct node *clone(struct node *head)
{
HasMap h=new HashMap();
struct node *current1,current2,*prev=NULL,*head2;
for(current1=head;current1;current1=current1->next)
{
temp=malloc(sizeof(struct node));
temp->data=current->data;
if(prev==NULL)
{
head2=temp;
}
else
{
prev->next=temp;
}
h.put(current1,temp);
prev=temp;
h.put(current,temp);
}
for(current1=head,current2=head2;current1;current1=current1->next)
{
current.ptr=h.get(current.ptr);
}
return head2;
}

- brahmasani99 May 24, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

// arbitrary pointer linked list :)
// code have the complexity equals O(n)
struct node *createCopy(struct node *L)
{
struct node *temp,*temp1,*head;
if(L==NULL)
return NULL;
temp=L;
while(temp!=NULL)
{
if(!head)
{
head=(struct node*)malloc(sizeof(struct node));
temp1=head;
temp1->next=temp->next;
temp->next=temp1;
temp=temp1->next;
}
temp1=(struct node*)malloc(sizeof(struct node));
temp1->next=temp->next;
temp->next=temp1;
temp=temp1->next;
}

for(temp=L;temp!=NULL;temp=temp->next->next)
{
temp->next->arbit=temp;
}
temp=L;
while(temp!=NULL)
{
temp->next->arbit=temp->arbit->next;
temp1=temp->next;
temp->next=temp->next->next;
temp->next=temp->next->next;
temp=temp->next;
}

return head;



}

- geeks July 28, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1) Create the copy of node 1 and insert it between node 1 & node 2 in original Linked List, create the copy of 2 and insert it between 2 & 3.. Continue in this fashion, add the copy of N afte the Nth node
2) Now copy the arbitrary link in this fashion

original->next->arbitrary = original->arbitrary->next; /*TRAVERSE
TWO NODES*/

This works because original->next is nothing but copy of original and Original->arbitrary->next is nothing but copy of arbitrary.
3) Now restore the original and copy linked lists in this fashion in a single loop.

original->next = original->next->next;
copy->next = copy->next->next;

4) Make sure that last element of original->next is NULL.

Time Complexity: O(n)
Auxiliary Space: O(1)

- Akash Verma February 09, 2012 | 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