代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast -> next)
{
slow = slow -> next;
fast = fast ->next ->next;
if(slow == fast)
return true;
}
return false;
}
分析:
slow一次走一步,fast一次走两步
若不带环:fast走到尾为NULL
若带环:slow和fast一定会再环里相遇
问题延伸:
1.为什么slow走一步,fast走两步一定会在环里相遇,会不会永远追不上,请证明!
不会,假设slow 进环 的时候,fast和slow的距离是N,紧接着的过程中,fast往前走两步,slow走一步,每次他们的距离缩小1,总会相遇,不存在跳过的情况。
2.slow 走一步,fast走3步?走4步?走x步行不行?为什么?请证明!
假设slow进环的时候,fast跟slow的距离是N,之后的过程中,fast往前走三步,slow走一步,他们每一次距离缩小2,当N为偶数的时候,他们一定会相遇,当N是奇数时,且环的长度C为偶数时,那么就会一直错过。
3.求环的入口点
由公式得到:一个指针从相遇点走,另一个指针从起点走,他们一定会在入口点相遇:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow = head,*fast = head;
while(fast && fast -> next)
{
slow = slow ->next;
fast = fast ->next ->next;
if(slow == fast)
{
//相遇
struct ListNode* meet = fast;
while(meet != head)
{
meet = meet ->next;
head = head -> next;
}
return meet;
}
}
return NULL;
}