思路:(1)设置两个快慢指针fast和slow。
(2)fast一次走两步,slow每次走一步。
(3)如果有环,那么fast一定会在环中和slow相遇。如果没环,则不会。
代码为
bool hasCycle(struct ListNode *head) {
struct ListNode *slow=head;
struct ListNode *fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
return true;
}
}
return false;
}
证明:(1)快指针是如何追上慢指针的?
(2)如果慢指针一次走一步,fast指针走两步,那么fast走三步,走四步行不行?
思路:方法一:利用链表相交的原理,fast和slow一定会在环中相遇,相遇点设为meet。
然后从meet这里断开,这下问题就转变为求两个链表相交,求相交节点。
代码为
//求两个链表相交的交点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *curA=headA;
struct ListNode *curB=headB;
int lengthA=0,lengthB=0;
while(curA)
{
lengthA++;
curA=curA->next;
}
while(curB)
{
lengthB++;
curB=curB->next;
}
int gap=abs(lengthA-lengthB);
struct ListNode * less=headA;
struct ListNode * great=headB;
if(lengthA>lengthB)
{
great=headA;
less=headB;
}
while(gap--)
{
great=great->next;
}
while(great)
{
if(great==less)
return great;
else{
great=great->next;
less=less->next;
}
}
return NULL;
}
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *slow=head;
struct ListNode *fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
break;
}
}
if(fast==NULL||fast->next==NULL)
return NULL;
struct ListNode *list2=fast->next;
fast->next=NULL;
struct ListNode *meet= getIntersectionNode(head,list2);
return meet;
}
方法二:
代码为
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *slow=head;
struct ListNode *fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
break;
}
}
if(fast==NULL||fast->next==NULL)
return NULL;
struct ListNode *meet=fast;
while(meet!=head)
{
meet=meet->next;
head=head->next;
}
return meet;
}