CareerCup-2.5
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
我写了第一个方法,时间复杂度是Ο(n^2),答案是第二个方法,想了会才明白,复杂度是Ο(n)
#include <iostream>
using namespace std;
// Creating a Linked List:
struct Node
{
Node(int d):data(d){next = NULL;};
int data;
Node* next;
};
Node* findPar(Node* head)
{
if(head == NULL) return NULL;
Node *p, *q = head->next;
int countq = 0, countp = 0;
while(q != head && q != NULL)
{
countq ++;
p = head;
countp = 0;
while(p != q)
{
countp ++;
p = p->next;
}
if(countp != countq)
return p;
else
q = q->next;
}
if(q == head)
return head;
else
return NULL;
};
/* 设head距离环交点k,环长度为n。q以2倍p的速度前进。p到达环交点的时候
* q已走出环交点k步,q向前n-k步是p。继续前进当他们相遇时,p又走出n-k步,
* 距离环交点n-k。q回到head,与p以相同速度前进,q走到环交点的时候p距离
* 环交点n,他们此时在交点相遇。
*/
Node* findPar2(Node* head)
{
Node *p = head;
Node *q = head;
while(p->next != NULL)
{
p = p->next;
q = q->next->next;
if(p == q)
{
break;
}
}
if(q->next == NULL)
{
return NULL;
}
p = head;
while(p != q)
{
p = p->next;
q = q->next;
}
return q;
};
int main()
{
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(4);
head->next->next->next->next = new Node(5);
head->next->next->next->next->next = head->next->next;
cout<<findPar(head)->data<<endl;
cout<<findPar2(head)->data<<endl;
system("pause");
};