Amazon Interview Question for Software Engineer / Developers


Country: India
Interview Type: In-Person




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

Cant you do it in O(2n) by traversing it twice?
Once for making it and the other traverse for cloning the external links.

- King@Work February 05, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The problem is how to fill in the random links on the 2nd pass. On the original list, the random pointer will point to a member of the list, but how to determine which member it is?

One way is to keep a map of original node pointers to Int, where Int is the position of the node in the list.

Scan through the original list once building an array of new nodes, and a map of old nodes to position.

Then fix up the random pointers in the new linked list using the map to look up the position, and the array to find the right new node.

You can then delete the array and the map. You have complexity of 2n, but of course you have used extra space.

- aomega February 05, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can there be duplicates? If no then its easy to do it.

- King@Work February 05, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Duplicates of what? It is a linked list. I would assume that there could be duplicate values within the list.

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

Using a hash map can solve this. They key will be the address of the given node external link and its value will be the address of the newly made node of the duplicate list.

- King@Work February 05, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here is a solution for it in javascript (node.js)

It marks the original objects with their index, then builds an array to represent the new linked lists (thus making it indexable). Then it fixes up the random links. The it deletes the tag it put on the original object. Thus it does it in 2 passes and uses an array plus a tag temporarily.

In Java, you would use a dictionary of objects rather than marking the original nodes of the list. I'm not sure how to create a map where objects are the keys in javascript.

var n = {data: 25, next: {data: 57, next: {data:2, next: {data:6, next:null

};

n.random = n.next.next;
n.next.random = n;
n.next.next.random = n.next.next;
n.next.next.next.random = n.next;

function show(n) {
do {
console.log('data: ' + n.data + ', random: ' + n.random.data);
n = n.next;
} while(n);
}

function copy(n) {
var newNodes = [];
var p = n;
var i = 0;
while(p) {
newNodes.push({data: p.data});
p.index = i++;
p = p.next;
}
p = n;
i = 0;
while(p) {
newNodes[i].next = newNodes[i+1];
newNodes[i].random = newNodes[p.random.index];
++i;
p = p.next;
}
p = n;
while(p) {
delete p.index;
p = p.next;
}
return newNodes[0];
}
console.log('original: ');
show(n);
console.log('copy: ');
show(copy(n));

- aomega February 06, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

We need to store pointers of the node in original list in a heap (along with its order of appearance).
Now simply create nodes (no links) for all the elements of first list and store them in another heap (with same order of oppearance)
Traverse each node of first list and look up for index of the node-addresses it is linked to. Do similar linking for second set of nodes.

- saga February 11, 2012 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

Check the solution at geeksforgeeks

- googlybhai February 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The solution proposed works pretty well...

After create a replica with regular next links

insert then given linked list into the new replica in a way that node1 of original comes before the node1 of replica.

Let me name node1 of original as node1_orig and
node1 of replica as node1_rep.

node1_rep->rand = node1_orig->rand->next;

After which we can remove the alternating original node to get the replica with with random pointers.

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

yes we can do it...

In first parse make the clone of the original linklist. Along with this we need to create 2 tables..

1 -- Address of original node , Coresponding Clone node..

2 -- Original node , random node pointer

In the 2nd parse first check the first node is which random node from table 2, find the corresponding node in clone linklist from table 1. link the result to corresponding node in clone link list.

- Sanjay Kumar February 08, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

//given start of linked list : start;

*pointer start,start',nextNode,nextNode'; 

// each node conatin one pointer 'next' and another 'rand' with obvious purposes.

//Part 1 : create clone linked list where rand pointer of each clone is pointing to element pointed by original element of that clone,
//	  and rand pointer of each original node pointing to its cloned node.

nextNode = start;
start'=null;
while(nextNode!=null){
	if(start'==null){
		start' = createClone(nextNode);
		nextNode'=start';
	}
	else{
		nextNode'->next=createClone(nextNode);       //createClone creates a memory for similar node pointer having value as 
							      //argument node and next pointer pointing to null;
		nextNode'=nextNode'->next;
	}
	nextNode'->rand=nextNode->rand;
	nextNode->rand=nextNode';
	nextNode=nextNode->next;
}

//Part 2 : Point next pointer of each clone to the rand element of respective original nodes 
//	 and rand pointer of each clone to point to cloned rand node

nextNode=start;
nextNode'=start';
while(nextNode!=null){
	*pointer temp = nextNode'->next;
	nextNode'->next=nextNode'->rand;
	nextNode'->rand=nextNode'->rand->rand;
	nextNode=nextNode->next;
	nextNode'=temp;
}


//Part 3 : Point each original node 'rand' pointer to original rand node,
//	and clone node's next pointer to next cloned node.

nextNode=start;
nextNode'=start';
while(nextNode!=null){
	nextNode->rand=nextNode'->next;
	nextNode'->next=nextNode->next->rand;		//null check the value and assign null if nexttNode->next is null;
	nextNode=nextNode->next;
	nextNode'=nextNode'->next;
}	


So, finally 
start : pointer to original linked list and
start' : pointer to cloned linked list.

- Sid February 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Time complexity of each part(3 parts) is : exactly n.
So, total time complexity of this algorithm is 3n, which is way less that O(n^2).

- Sid February 06, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This concept has been explained with a diagram over here
(nobrainer. co. cc)

- Anony February 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

One way is we can visualize the structure as a graph.
1. Do regular BFS on source graph
2. In addition to that every time you de-queue, for each in source set, if not visited , in the clone set create a new node and assign a pointer to the new node. If visited the just assign a new pointer.

- geekvsgik February 06, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

yes we can do it...

In first parse make the clone of the original linklist. Along with this we need to create 2 tables..

1 -- Address of original node , Corresponding Clone node..

2 -- Original node , random node pointer

In the 2nd parse first check the first node is which random node from table 2, find the corresponding node in clone linklist from table 1. link the result to corresponding node in clone link list.

- Sanjay Kumar February 08, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

yes we can do it...

In first parse make the clone of the original linklist. Along with this we need to create 2 tables..

1 -- Address of original node , Corresponding Clone node..

2 -- Original node , random node pointer

In the 2nd parse first check the first node is which random node from table 2, find the corresponding node in clone linklist from table 1. link the result to corresponding node in clone link list.

- Sanjay Kumar February 08, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

yes we can do it...

In first parse make the clone of the original linklist. Along with this we need to create 2 tables..

1 -- Address of original node , Corresponding Clone node..

2 -- Original node , random node pointer

In the 2nd parse first check the first node is which random node from table 2, find the corresponding node in clone linklist from table 1. link the result to corresponding node in clone link list.

- Sanjay Kumar February 08, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In Java

public class ArrayCloner {

	public class Node {
		int value;
		Node next;
		Node random;
		
		//getters, setters & contructors
	}
	private Map<Node,Node> nodeMap = new HashMap<Node,Node>();
	public Node cloneArray(Node head) {
	
		if(head == null) {
			return null;
		}
		
		Node newHead = new Node();
		Node currentNewNode = newHead;
		Node currentNode = head;

		while(currentNode != null) {
			currentNewNode.value = currentNode.value;
			nodeMap.put(currentNode,currentNewNode);
			if(currentNode.next != null) {
				currentNewNode.next = new Node();
			}
			currentNewNode = currentNewNode.next();
			currentNode = currentNode.next();
		}
		
		currentNewNode = newHead;
		currentNode = head;
		
		while(currentNode != null) {
			currentNewNode.random = nodeMap.get(currentNode.random);
			currentNewNode = currentNewNode.next();
			currentNode = currentNode.next();
		}
		
		return newHead;
		
	}
}

- Usman February 17, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is my solution

#include <stdio.h>
#include <stdlib.h>

typedef struct __LinkedListNode__ {
    int data;
    struct __LinkedListNode__* next;
    struct __LinkedListNode__* link;
} LinkedListNode;

LinkedListNode* clone_list(LinkedListNode* head) {
    LinkedListNode* trav = head;
    LinkedListNode* clone = NULL;
    LinkedListNode* cloneHead = NULL;

    if (head == NULL)
        return NULL;

    while (trav) {
        clone = malloc(sizeof(LinkedListNode));
        clone->data = trav->data;
        clone->next = trav->next;
        trav->next = clone;
        trav = clone->next;
    }

    trav = head;
    cloneHead = trav->next;

    while (trav) {
        trav->next->link = trav->link->next;
        trav = trav->next->next;
    }

    trav = head;
    while (trav) {
	    clone = trav->next;
        trav->next = clone->next;
        trav = clone->next;
        if (clone->next)
            clone->next = clone->next->next;
    }

    return cloneHead;
}

void destroy(LinkedListNode* head) {
    LinkedListNode* node;
    while (head) {
        node = head;
        head = head->next;
        free(head);
    }
}

void print_list(LinkedListNode* head) {
    while (head) {
        if(head->link)
            printf("data:%d ldata:%d\n",head->data, head->link->data);
        else 
            printf("data:%d ldata:NULL\n",head->data);
        head = head->next;
    }
}

int main() {
    LinkedListNode *node1, *node2, *node3, *node4, *clone;

    node1 = malloc(sizeof(LinkedListNode));
    node1->data = 1;

    node2 = malloc(sizeof(LinkedListNode));
    node2->data = 2;

    node3 = malloc(sizeof(LinkedListNode));
    node3->data = 3;

    node4 = malloc(sizeof(LinkedListNode));
    node4->data = 4;

    node1->next = node2;
    node1->link = node3;

    node2->next = node3;
    node2->link = node4;

    node3->next = node4;
    node3->link = node2;
	
    node4->next = NULL;
    node4->link = node4;
	
    clone = clone_list(node1);
	
    printf("Original\n");
    print_list(node1);
    printf("\nClone\n");
    print_list(clone);
    printf("\n");
	
    destroy(node1);
    destroy(clone);
    return 0;
}

- sanil February 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

// creating a clone of the nodes of the list
// the next pointers of the original list will
// be pointing to the corresponding node in the copy list
// the next pointers of the copy list will be 
// pointing to the next node of the corresponding node
// in the original list
p = head
while (p != null) {
  q = clone(p)
  q.next = p.next
  p.next = q
  p = q.next
  // random pointer of q points to nowhere at this point
}
// copying random pointers to the copy list
p = head
while (p != null) {
  q = p.random.next
  p.next.random = q
  p = p.next.next
}
// fixing the next pointers in the two lists
p = head
copyhead = p.next
while (p != null) {
  q = p.next
  p.next = q.next
  q.next = p.next.next
  p = p.next
}
return copyhead

- amshali February 22, 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