力扣原题位置
解题思路:
两个指向头结点的指针,快的走两步,慢的走一步,快针后面没结点时(偶数个结点),或者快针已经走到了空针(奇数个结点)时,走完链表,如果快针和慢针相遇了,说明有环。假设环起点距离两针相遇点m,慢针走了k步到达相遇点时,快针一定走了2k步,即多走了k步,这k步就是在环内转圈,k是从相遇点为起点的圆的整数倍,转换一下就是从环起点开始的圆的整数倍,对于环外情况的慢针,走了k步,相遇点距离环起点m步,所以从head走k-m步就是环起点,对于环内走的情况,因为两针在同一点,任选一针从相遇点走k-m步也会到环起点,即任一指针回到head,同时走一样的步数,相遇点就是环起点。
labuladong解题思路
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow,*fast;
slow = fast = head;
//最后有可能走不了两步
while(fast != NULL && fast->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(fast == slow){
//有环,退出
break;
}
}
//未提前退出,走完了,无环
if(fast == NULL || fast->next == NULL){
return NULL;
}
//有环情况,找起始点,任一指针回到head,两指针同步走k-m步
slow = head;
while(fast != slow){
slow = slow->next;
fast = fast->next;
}
return slow;
}
};