Microsoft Interview Question for Software Engineer / Developers






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

1. Save the position where the Slow and Fast pointers meet. (Say the point is 'A')
2. Find the loop count (i.e number of elements in the loop) - do this by keeping the Fast pointer at point 'A' and moving the Slow pointer one position at a time and incrementing the a counter. Say the counter reads 'S' when the Slow pointer meets the Fast pointer. This means the loop size/count is 'C'.
3. Now the point in the link list where the loop starts is the 'C'th node from the end of the link list. Now use the algo to find the 'n' node from the end of the link list and you have the answer.

- N March 03, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

what do you mean by "end of link list"..its a loop ..

- kb May 14, 2012 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

What you need:
two ptrs - a fast ptr and a slow ptr
fast ptr is always one node ahead of the slow ptr

Whenever the slow ptr leaves a node it marks that node - say alters the data such that if data=5 it makes it 5000.

Whenever the fast ptr arrives at a node it checks if the node is marked -- say checks if data/1000 is an integer.

So if your linked list is like this:

O---O----O-----O-----O---O
....|____________________|

Step(1):
f,s
.O---O----O-----O-----O---O
.....|____________________|

Step(2):
.....s....f
.@---O----O-----O-----O---O
.....|____________________|


Step(3):
..........s.....f
.@---@----O-----O-----O---O
.....|____________________|


Step(4):
................s.....f
.@---@----@-----O-----O---O
.....|____________________|


Step(5):
......................s...f
.@---@----@-----@-----O---O
.....|____________________|



Step(6):
.....f....................s
.@---@----@-----@-----@---O
.....|____________________|


Here f checks if @/1000 = O and it is true so we found the last node in the list which is pointed to by 's' which is the slow ptr


Only thing is how to mark the nodes properly. obviously multiplying by 1000 might not work in all cases. Need some unique function.

- chimaera April 10, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

There is no solution! Where do a circle end or begin? Which comes first the Chicken or the egg?

- Just Me January 26, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

step 1: Do slow pointer and fast pointer stuff. Start counter M when they start traversing. and stop the counter when they meet ( Mth node from list head)
step 2: Now from meeting point. Start another counter C and move slow pointer until it meets fast pointer ( C is the size of the loop)
step 3: (C - (M - C) )th node from the meeting place is the node you want.

- Carbon April 01, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Every problem having a solution, This solution needs
O(n) space in which you store all the node.

- sourabh February 16, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You can also do it with o(1) space and o(n^2) time.

I'll post an algorithm if no one else comes up with it.

- Anonymous February 18, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you please tell how to do that in 0(1) space ???

- Anonymous1 March 28, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi
It can be done even in O(n) time using O(1)space.

- Ravi Kant Pandey March 29, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi,
starting from the first node,node next to number of nodes which are not in loop is the start of the loop.

- Ravi Kant Pandey March 29, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

can i read this question as how to find a loop in linked list. If you know how to find loop then u know where the loop begins :)

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

use bit vector

- Anonymous March 03, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the element sof linked list do not have to be int

- J May 03, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Hi,

if there is O(n) space then
following solution works

store the node's ptrs in an array of linked list while reversing u will end up where u started.

again reverse it comparing with the ptr stored in array . first time when it doesnt match. the ptr stored in last index which matches is the start of the loop.this time u will end up with original linked list.


ravi_cdotd@yahoo.co.in

- Ravi March 23, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hey can anyone post the algo for this.

- Raj March 23, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

//loop is detected by reversing the link list now to regain original list it has been reversed once more.
#include<stdio.h>
struct lnlst{
int info;
struct lnlst *next;
};


struct lnlst* reverse(struct lnlst* ,struct lnlst * []);

void main()
{
struct lnlst *ls,*temp,*ptr;

struct lnlst *a[100],*b[100];
int i;

//Preparing a linked list with loop
ls=(struct lnlst*)malloc(sizeof(struct lnlst));
ls->info=15;
temp=ls;
for(int i=0;i<10;i++)
{
temp->next=(struct lnlst*)malloc(sizeof(struct lnlst));
temp=temp->next;
if(i==5)
ptr=temp;
temp->info=i;
}
temp->next=ptr;
// temp->next=NULL;


// link list preparation completed.


//printing link list
temp=ls;
printf("\nData with index:");
for(int i=0;i<30 && temp !=NULL;i++){//15 elements are displayed to include loop
printf("\t(%d)%d",i,temp->info);
temp=temp->next;
}

//printing completed



temp=0;

//reversing first time.
temp=reverse(ls,a);
if(temp==ls)
printf("\nNOTE:There is Loop in the link list");
ls =temp; //it is included to cater if there is no loop.

//reversing second time.
ls=reverse(ls,b);


//printing addresses
printf("\ni a[i] b[i] ");
i=0;
while(a[i] && b[i]){
printf("\n%d %ld %ld\n",i,a[i],b[i]);
i++;
}

//printing addresses completed


//comparing addressed
i=0;
while(a[i]==b[i])
i++;

printf("\n\nLoop starts from node address: %ld at index %d\n",a[i-1],i-1);

}

struct lnlst* reverse(struct lnlst *ls ,struct lnlst* ar[])
{
struct lnlst *temp,*prev,*current;
int i=0;
prev=0;
temp=0;
current=ls;

ar[i++]=current;

while(current->next)
{
temp=current->next;
current->next=prev;
prev=current;
current=temp;
ar[i++]=current;
}
ar[i]=NULL;
current->next=prev;
return(current);
}

- Ravi Kant Pandey March 28, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

there might be a problem

if it looks like this

1->2->3->4->3

after reversing, it is the same.

- ppp October 07, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

nice!!!!!!!!

- Ravi Kant Pandey March 28, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In the previous comment -- in step(6) the f is on Node:2 and s is on Node:6

- chimaera April 10, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

To find the node which forms the start of the loop:

1. use the double pointer (p and q) technique to establish that a loop exists. If a loop does exist, then the pointers meet on a node forming the loop.

2. if a loop does exist, then for each node (use a third pointer here, r) starting from the head, we check if it forms the start of the loop by using p to loop around and checking on each iteration if it meets r. If it meets then node r is the one, else increment r and repeat step 2

Step 1 requires O(n) time, while step 2 requires O(n^2) time. However, it requires O(1) space.

Is it possible in O(n) time and O(1) space??

- k June 22, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote
{{{ // use 2 pointers p1 and p2. p1 is slow and p2 is fast. bool checkCircular( Node *head, Node & p) { Node * p1 = head; Node *p2 = head; while (p2 !=NULL) { p1 = p1->next; p2 = p2->next->next; if (p1==p2) p = p1; return true; } return false; } - jj August 22, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

read the question .. u dumb F ..!

he is asking for juice.. U give him an orange.

- W t f January 30, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

most people byheart soution, they are truly dumb and they confuse too .. the question is to find the node and people are putting solutions for finding a circle.

- by hea August 02, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct Node{
bool fVisited; // initialized to false before calling FindBrokenLink
Node *pNext;
};

Node* FindBrokenLink(Node* pStart)
{
Node* pCurrent = pStart;
while(pCurrent)
{
Node* pNext = pCurrent->pNext;
if(pNext->fVisited)
return pCurrent; // this is where the last node pointing somewhere in the middle
pCurrent = pNext;
pCurrent->fVisited = true;
}
}

- uxa August 23, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Oops one correction

struct Node{
bool fVisited; // initialized to false before calling FindBrokenLink
Node *pNext;
};

// return_value == NULL : no circular refs
// return_value != NULL : pointer to the circular reference
Node* FindBrokenLink(Node* pStart)
{
Node* pCurrent = pStart;
while(pCurrent)
{
Node* pNext = pCurrent->pNext;
if(pNext->fVisited)
return pCurrent; // this is where the last node pointing somewhere in the middle
pCurrent = pNext;
pCurrent->fVisited = true;
}
return NULL; // no broken links
}

- Anonymous August 23, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

it should be:
pCurrent->fVisited = true;
pCurrent = pNext;

not as:
pCurrent = pNext;
pCurrent->fVisited = true;

- Ramu September 22, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I feel this should work...

fast=head;
slow=head;
fast -> intially incremented by two. fast=fast->next->next
slow -> incremented by one. slow=slow->next;
while(true){
if(fast==null || fast->next==null)
return null;
if(fast==slow || fast->next==slow)
break;
fast=fast->next->next;
slow=slow->next;
}
thirdPtr=head;
while(true){
if(thirdPtr==fast || thirdPtr == slow)
break;
thirdPtr=thirdPtr->next;
}
return thirdPtr;
}
The idea is that by this method either fast or slow would end up pointing to the start node. To find which is first we need a third ptr. The ptr tht the third ptr meets is the start. Anyone can prove me wrong?

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

I think i missed one case where the last pointer points to the first node, then when the cycle is detected the slow will be always at the tail ptr. Hence when fast is incremented everytime, it needs to be checked if it passes through the head, if true then return the head ptr. I guess only this case is special, for the rest it hold good --> where the tailptr points to a node other than the head.

- Anonymous October 02, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Wrong !
1-2-3-(4-5-6-7-8-9-10)-(4..10)-....
slow fast
1 1
2 3
3 5
4 7
5 9
6 4
7 6
8 8
8 does not point to the start !

- Vel October 30, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

IMHO, the circularity can be found by having two ptrs both starting at the head, with ptr1 incrementing by one while ptr2 incrementing by 2. We can detect circularity when ptr1==ptr2. If we have counters for each of the ptrs say c1, c2, respectively; we have this simultatneous eaqution :
p + k = c1 //where p is prefix length before the start of the cycle
p + 2k = c2 // k is the lenght of the cycle.

If we solve for p we get p = 2c1 - c2; and thats how far the cycle starts from the head of the original list.

- sb October 14, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

what is C1 and C2.

- Raj November 03, 2007 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Slow pointer and fast pointer works ... .but it tells that there is a cycle ... to find where the cycle starts..

Initially save the position where the slow and fast meet ( they always meet within the cycle)
Now from the head count the number of nodes in between the head and the saved node.
Now do it again till the next node of the saved node(save the node i.e.,(savednode->next) inplace of the saved node) ...do this process it untill the counter decrements.
Once the counter decrements the savednode is the last node of the cycle.

- Vamsi December 05, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I believe my aglo works in O(n) time and O(1) space
p1 and p2 are two pointers

p1 travels 2 times faster than p2 and will meet because of the loop.

then from this point we can get the number of nodes in the loop by walking around the loop once again. and also we can get the number of nodes in the list by walking from header and stop when meeting p1 twice.

from the diffrence between those two numbers, finding the starting node of the loop is easy.

- Anonymous March 22, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

looks good to me :)

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

Wrong!!!

walking from header till we meet p1 twice wont give number of nodes in loop. It gives number of nodes in loop+ number of nodes from head to P1 which is not equal to number of nodes in loop. If that was the case then u would have got ur answer there only.

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

.

- gauravk.18 April 06, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

i=0;
Element ele = get(i);
idx = list.indexOf(ele);
if idx != i then return idx;
i++

- ms_emp June 07, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

O(n) time & space

Node lv; // last visited
c=head;
while(1)
{
if (c->next==null)
return lv;
lv=c;
c=c->next;
lv->next=null;
}

- Rawfish June 08, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

//find the meeting point
p1=p2=head;
while (TRUE)
{
p1=p1->next;
p2=p2->next->next;
if (p1==p2)
break;
}

//find the required node
p1=head;
while (p1->next!=p2->next)
{
p1=p1->next;
p2=p2->next;
}

Now p2 point to the required node

- Darren June 12, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

there is problem for Darren's solution. You assume that before p1 and p2 meet, p2 walkes exactly one loop. This is not true, p2 may take n loops before meeting with p1.

- lensbo July 16, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can anybody really come up with a O(n) time and O(1) space algo?
To sum up the above algos, a typical 2-phase algo is:
-----------------------------------------------------
step1: find the loop. O(n) time and O(1) space.
-------------------------------------------------------
step2: find the meeting node. I can think of two ways:
algo 1. use 2 stacks, stack 1 is used to record all the nodes starting from head. stack 2 is used to record all the nodes starting from step1. And then pop the nodes from the 2 stacks to see if they match. This algo use O(n) space.
algo 2. use recursion method. This should be O(1) space. But I am not sure if this is doable.

- XYZ September 18, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Just figured out the algo posted by Anonymous on Saturday March 22, 2008. His algo should be O(n) time and O(1) space. I'd like to elaborate his algo:
see the length of the list (L1) starting from head is 10, and the length of the list (L2) starting from where the circle is found is 15, then start from L2[5], and L1[0], and compare the two nodes. so on and so forth, until find the first node that are equal.

- XYZ September 18, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

after 1 month and I came back to see my post again, I am confused by myself. And it took me half an hour to figure out what I said. Let me try to explain it more clearly:
=================================
1. p1 and p2 meet at Node K.
2. calculate the size of the loop: starting from Node K, do iteration, i++, until it comes back to Node K again, and the size of the loop=i;
3. find where the loop start. use 2 pointers p1 and p2.
Initialization:
p1=List[0],
p2=List[i],
p1 and p2 step 1 node each time. and compare if p1==p2. If at Node N p1==p2, then loop starts at Node N.

- XYZ November 19, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

package myLinkedList;

public class findCycle {

private class Node {
int data;
Node next;
}

Node head = null;

private void createList() {
if (head == null) {
head = new Node();
head.data = 15;
}
Node cur = head;
Node cycPtr = null;
for (int i = 0; i < 10; i++) {
Node temp = new Node();
temp.data = i;
cur.next = temp;
cur = cur.next;
if (i == 5) {
cycPtr = temp;
}
temp.next = cycPtr;
}
}

private void display() {
Node cur = head;
for (int i = 0; i < 25; i++) {
System.out.println(i + " " + cur.data);
cur = cur.next;
}
}

public Node reverse(Node a[]) {
Node cur, prev = null, temp;
cur = head;
int i = 0;

while (cur.next != null) {
temp = cur.next;
cur.next = prev;
prev = cur;
cur = temp;
a[i++] = cur;
}
a[i] = null;
cur.next = prev;
return (cur);
}

public void checkCycle() {
Node a[] = new Node[20];
Node revHead = reverse(a);
if (revHead == head) {
System.out.println("Cycle Detected!");
}
}

public void checkCycleStart() {

Node a[] = new Node[20];
Node b[] = new Node[20];

Node revHead1 = reverse(a);
Node revHead2 = reverse(b);
int i = 0;
System.out.print("A : ");
displayArray(a);
System.out.print("B : ");
displayArray(b);

while (a[i] == b[i]) {
i++;
}

System.out.println("The cycle starts from " + i
+ "th node which is node " + a[i - 1].data);
}

public void displayArray(Node a[]) {

for (int i = 0; i < 20; i++) {
if (a[i] != null)
System.out.print(a[i].data + " ");
}
System.out.println("");
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
findCycle myObj = new findCycle();
myObj.createList();
myObj.display();
myObj.checkCycle();
myObj.checkCycleStart();
}

}


/* Output

0 15
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
11 5
12 6
13 7
14 8
15 9
16 5
17 6
18 7
19 8
20 9
21 5
22 6
23 7
24 8
Cycle Detected!
A : 0 1 2 3 4 5 9 8 7 6 5 4 3 2 1 0 15
B : 0 1 2 3 4 5 6 7 8 9 5 4 3 2 1 0 15
The cycle starts from 6th node which is 5
*/

- Laks September 23, 2008 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

struct node{
int data;
int flag=0;
node* next;
}
node* findStart(node* head){

node* curr=head;
while(curr!=NULL){
(curr->flag)++;
if(curr->flag==2)
return (node);
curr=curr->next;
}
return;
}

- neo September 24, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can anyone let me know if this works and if this is a good approach of introducing one more field in linked list.

- neo September 24, 2008 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can anyone traverse this example and show how the beginning of the loop can be detected? Thanks in advance!

3->5->2->1->7_
      |_______|

- MakeItWork August 29, 2009 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey72781" class="run-this"> SingleLinkedListNode<int> normalNode = head;
SingleLinkedListNode<int> twoWayFasterNode = head;

while (twoWayFasterNode != null)
{
normalNode = normalNode.Next;
twoWayFasterNode = twoWayFasterNode.Next.Next;
if (normalNode == twoWayFasterNode)
{
normalNode = head;
while (normalNode != twoWayFasterNode)
{
normalNode = normalNode.Next;
twoWayFasterNode = twoWayFasterNode.Next;
}
break;
}
}

return twoWayFasterNode;
</pre><pre title="CodeMonkey72781" input="yes">
</pre>

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

We could use a Hashtable and check to see the repeated node. This would take O(n) time and O(n) space.

- NewGuy October 24, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 0 vote

Use the two pointer approach to detect cycles in a linked list (tekpool.wordpress.com/2006/09/27/linked-list-detect-a-cycle-in-a-linked-list-two-pointers-approach-slow/) and when ptr_first == ptr_second, print the node where this happens.

- Lown Mower May 02, 2007 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The link above only helps in detecting cycles, but does not help in finding where circular linked list starts.

as per this logic, 5 would be the output of where the circular linked list starts which is incorrect. The node should be 3.

1---2----3----4---5---6
| |
| |
--------------


Step 1 2 3 4 5 6 7 8
p 1 2 3 4 5
q 1 3 5 3 5

- tSc August 20, 2007 | Flag


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