LeetCode142环形链表
思路:
快慢指针,fast步长为2,low步长为1,快慢指针相遇则有环,快指针至少绕环一圈才会赶上慢指针,会在环内相遇,然后就是考虑怎么找环的入口
首先,head—a---->环入口----b—>相遇点—c---->环入口
快指针的速度是慢指针的两倍,那么同时间段走过的路程,快指针是慢指针两倍
low:a+b
fast:a+b+n(b+c)
得出等式:2(a+b)=a+b+n(b+c)
整理一下:a=(n-1)(b+c)+c
a:从head------>环入口的距离
b+c:一圈环的距离
c:从相遇点到环入口的距离,这个等式就是说,相遇后,一个指针从head走,一个指针从相遇点同时同步长开始走,会在绕n圈+从相遇点到入口的距离相遇,此时相遇会在环入口,也就是第一次相遇就在环入口
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head)
{
//1.定义快慢指针
struct ListNode*low;
struct ListNode*fast;
low=head;
fast=head;
while(fast!=NULL&&fast->next!=NULL)//fast必须有两个节点才能执行fast->next->next不然会出现空指针访问,造成异常
{
//low步长为1,fast步长为2
low=low->next;
fast=fast->next->next;
if(low==fast)//相遇,找入口
{
low=head;
while(low!=fast)
{
low=low->next;
fast=fast->next;
}
return low;//返回环的入口
}
}
//循环完链表,low和fast未相遇,无环,返回NULL
return NULL;
}