
在解决环形链表的问题中,百分之九十的题目要用到快慢指针之一思维;
环形链表 根据数学推理可得,若链表中存在环,快指针一定会追上慢指针;

slow 和 fast 都初始化为链表的头节点 head。
循环的条件是 fast 和 fast->next 都不为空。这是因为如果链表中没有环,fast 或 fast->next 最终会指向 NULL,从而退出循环。
在循环中,slow 每次移动一步(slow = slow->next)。 fast 每次移动两步(fast = fast->next->next)。
如果链表中存在环,fast 和 slow 最终会在环内相遇(即 slow == fast)。 如果链表中没有环,fast 或 fast->next 会先到达链表的末尾(NULL),循环结束。
如果在循环中检测到 slow == fast,说明链表中存在环,返回 true。 如果循环结束,说明链表中没有环,返回 false。
在循环条件 while(fast && fast->next) 中,fast 必须先于 fast->next 进行检查。如果先检查 fast->next,当 fast 为 NULL 时,访问 fast->next 会导致空指针解引用错误。
如果输入的链表为空(head == NULL),代码会直接返回 false,这是合理的,因为空链表显然不存在环。
如果链表中存在环,fast 和 slow 会在环内相遇。此时,循环不会无限进行,因为快指针最终会追上慢指针。
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}假设链表中存在环,环的长度为 L,环的入口距离链表头部的距离为 D。
慢指针每次移动一步,快指针每次移动两步。 当慢指针进入环时,快指针可能已经在环内,也可能尚未进入环。 但无论如何,快指针最终一定会进入环。
一旦快指针和慢指针都在环内,它们之间的相对速度为 2−1=1 步。 假设快指针进入环时,它与慢指针之间的距离为 k 步(k 是环长度 L 的某个倍数或部分)。 每次循环,快指针会比慢指针多走一步,因此它们之间的距离会逐渐减少。 最终,快指针和慢指针一定会相遇。
另外无论快指针速度是慢指针的几倍,快指针任然会追上慢指针;

所以,在带环链表中,快慢指针相遇点和头节点到入环点的距离是相等的。这一结论可以用于在已知链表有环的情况下,寻找环的入口节点。 有了该结论,该题就会变的简单很多。
slow 和 fast 都初始化为链表的头节点 head。
循环的条件是 fast 和 fast->next 都不为空。这是因为如果链表中没有环,fast 或 fast->next 最终会指向 NULL,从而退出循环。
在循环中,slow 每次移动一步(slow = slow->next)。 fast 每次移动两步(fast = fast->next->next)。
如果链表中存在环,fast 和 slow 最终会在环内相遇(即 slow == fast)。 如果链表中没有环,fast 或 fast->next 会先到达链表的末尾(NULL),循环结束。
当 slow 和 fast 相遇时,说明链表中存在环。 此时,将一个指针(如 pcur)重新指向链表的头节点 head,另一个指针(如 slow)保持在相遇点。
同时移动 pcur 和 slow,每次各移动一步。 当 pcur 和 slow 再次相遇时,它们相遇的节点就是环的入口。
返回 pcur(或 slow),即环的入口节点。
如果循环结束时没有检测到环(即 fast 或 fast->next 为 NULL),返回 NULL。
typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
ListNode* pcur = head;
while(pcur != slow)
{
pcur = pcur->next;
slow = slow->next;
}
return pcur;
}
}
return NULL;
}