Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.
DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE
Input: A -> B -> C -> D -> E -> C [the same C as earlier]
Output: C
这题有2中做法,书上的那个还没仔细看(2个指针,一个+2,一个+1,如果重复了,就说明有环。但是怎么找到环的头节点呢?关键是:
在重复的时候,把slow重新指向head,同时把fast的速度改为一,那么他们再次相遇的时候就是环路的头了 )公式请参考hawstein。
I thinks the 2nd idea is simple as similar to early solution: use a hashmap to have key(node addr), if the addr is duplicate, it means there is a loop.
#include
#include
using namespace std;
typedef struct node{
int data;
node *next;
}node;
// initialize a linkedlist with a loop,
// the n is the total nodes, m is the starting
// node of the loop, still a singly linked list
node* init(int *a, int n, int m){
node *head, *p, *q;
for(int i=0; i
data = a[i];
if(i==m) q = nd;
if(i==0){
head = p = nd;
continue;
}
p->next = nd;
p = nd;
}
p->next = q;
return head;
}
// seems like a math contest idea
node* loopstart0(node *head){ // see the explaination
node *fast = head, *slow=head;
while(fast || fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast==slow)
break;
}
if(!fast || !fast->next) return NULL;
slow = head;
while(fast!=slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
// method 2: simple and easy to understand
map
hashmap;
node* loopstart1(node *head){
while(head){
if(hashmap[head]) return head;
else{
hashmap[head] = true;
head = head->next;
}
}
return head;
}
int main(){
int n =6, m =2 ;// m
data<
输出结果:
Executing the program....
$demo
3