本文参考代码随想录
给定一个链表,返回入环的第一个节点。若无环则返回null
判断链表是否有环
fast每次移动两个节点,slow每次移动一个节点,如果相遇则说明有环
找到环的入口
相遇时,slow走过的节点数为x+y,fast走过的节点数为x+y+n(y+z),n为fast指针在环内遇到slow时走过的圈数
因为fast速度是slow的两倍,则有
(x + y) * 2 = x + y + n(y + z)
得x + y = n(y + z)
x = (n - 1)(y + z) + z, 其中n >= 1
- 当n为1时,x = z,即:定义index1在相遇节点,index2在头结点,同时移动,相遇的节点就是环形入口
- n大于1时方法仍然相同
/**
* 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;
while(fast != NULL && fast -> next != NULL){
slow = slow -> next;
fast = fast -> next -> next;
if(slow == fast){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2){
index1 = index1 -> next;
index2 = index2 -> next;
}
return index2;
}
}
return NULL;
}
};
时间复杂度O(n)
空间复杂度O(1)