Adobe Interview Question
Software Engineer / Developers@Tully..how you can say that..p2 will travel only.(x+y+z+y)..may be it will travel (x+y+n*(z+y)) where n vary from 1 to any number depending upon size of loop..
Well said Om.
Lets see like this.
Loop size is y+z. suppose p1 iterates the loop n times before meeting p2. So in this case p2 will do 2n iterations. So when both p1 and p2 meets total node traveled by p1 is x+n(y+z) and total distance traveled by p2 is x+z+2n(y+z)
so we have (p2 is twice as fast as p1)
2p1 = p2
2(x+n(y+z))=x+z+2n(y+z)
=>x=z
@Tulley...
Lets..total length of linked list is 25 and size of loop in 4...
now please validate your logic...
@Tulley..I think your answer is correct nut explanation is not correct..
Let me try like this..
Let ..size of loop is L and length of rest is x..and assume they will meet at position y(from the first node of the loop)...
..then..
2(x+k1*L+y)=(x+k2*L+y)..where k1<k2 and k1 will have only value 0 or 1(but its not very impnt)..
so..
(x+y)=(k2-k1)*L...
this means that if we are at any node in linked list and if traverse (x+y)node then will again back at same position...
i.e. if we are at position y and traverse x+y node then we will reach again at y---> if we will traverse just x node from y then we will be at start node(first) of loop..if x=z as z=(L-y)..
..pls let me know if you have any prob with this...
Sorry..in 9th line it will..
this means that if we are at any node in loop and if traverse (x+y)node then will again back at same position.
@Om.. can you describe your logic for
1-2-3-4-5-6-7-8-9
and 9 points back to 2, then how your logic will detect first node in the loop?
int validateCircularList(node* head) {
map<signed int, int> addList;
map<signed int, int>::iterator it;
node* tail;
//add head
int add = (int) (head);
cout << endl;
cout << endl;
addList.insert(pair<signed int, int> (add, head->val));
//rest of the nodes
head = head->next;
do {
int tempAdd = (int) (head);
it = addList.find(tempAdd);
if (it == addList.end()) {
addList.insert(pair<signed int, int> (tempAdd, head->val));
tail = head;
if (head->next != NULL)
head = head->next;
else
return 0;
}
else {
cout << endl << "LOOP exists:" << endl;
cout << "loop starts = " << (head->val) << "and Loop ends = "
<< tail->val << endl;
return 1;
}
} while (1);
return 0;
}
I won't type the code here but I did the same problem few days back.
Algo----
take two pointers p1 & p2.
begin a loop moving p1 one node at a time and p2 2 nodes at a time while one of them reaches end OR they meet at some node.
If they meet loop is detected.
Now at the point where loop is detected start moving p2 one node at a time and begin a counter(keeping p1 at same position).
When they meet again this counter will give the size of loop.
Now when we have the size of the loop we start from the beginning node again.
Now offset p2 counter no. of nodes from the start.
Now keep moving p1 and p2 one node at a time. The point where they meet will give the starting point of the loop. Try to visualize with any example.
can some1 explain what the following line mean in above comment
Now offset p2 counter no. of nodes from the start.
1. let pointer p1 and p2 and p3 are pointing to the head of linked list.
- Tulley February 24, 20112. move p1 by one node and p2 by two node.
3. if loop exists p1 and p2 will meet at some node.
4. now start moving p3 and p1(or p2) by one node. p3 and p1(or p2) will meet at the node from where loop starts.
Proof:
let x=number of nodes from head to the node from where loop starts.
let y=number of nodes from the node from where the loop starts to the node where p1 and p2 meets.
let z=number of nodes from the node on which p1 and p2 meets to the node where loop starts.
Number of node traveled by p1 is x+y.
Number of node traveled by p2 is x+y+z+y.
since p2 is as fast as twice of p1 therefore
2(x+y) = x+y+z+y
=>x=z.
Thus the node from which loop starts is equidistant from the head and the node where p1 and p2 meets.