题目
思路
题可拆分为两个问题:
-
判断链表是否有环
-
如果有环,找到环的起点
1. 判断链表是否有环
设定快慢指针,fast走两步,slow走一步,如果二者能在结点处相遇,则链表必有环
2. 找到环的
假设环起点距离开始为x,结点到相遇处为y,相遇处到结点为z,可列出上述式子,也就是说当快指针在环内转一圈就可与慢指针相遇时,头结点出发一个指针同时相遇结点 出发一个指针,二者以相同的速度移动,二者相遇处即为环开始位置。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//定义快慢指针
ListNode *fast = head;
ListNode *slow = head;
//首先判断fast以及fast->next不为null
while((fast != nullptr) && (fast->next != nullptr))
{
//快指针走两步,慢指针走一步
fast = fast->next->next;
slow = slow->next;
//找环的入口,首先确定快慢指针相遇地点
while(slow == fast)
{
//相遇点设定指针
ListNode *temp1 = fast;
//head设定指针
ListNode *temp2 = head;
//head与相遇点处同步进行前移,相交处为环的入口
while(temp1 != temp2)
{
temp1 = temp1->next;
temp2 = temp2->next;
}
return temp1;
}
}
return nullptr;
}
};