题解
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast = head;
ListNode *slow = head;
while (fast != nullptr && fast->next!= nullptr){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
fast = head;
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
}
return nullptr;
}
};
思路
我没什么思路,就是快慢链表floyd环路,学就是了。
一个快指针每次前进两个节点,一个慢指针一次前进一个节点,如果快指针能走到头,那么说明没有环路,如果快指针走不到头,快指针和慢指针必相遇。快慢指针第一次相遇时把快指针移到链表头,快慢指针第二次相遇的节点就是环路开始的节点。
设头节点到环路开始节点距离为
m
m
m慢节点在环路里走了不足一圈的距离为
k
k
k,那么当快结点和慢节点第一次相遇时
2
∗
(
m
+
k
+
n
1
∗
l
)
=
m
+
k
+
n
2
∗
l
2*(m+k+n1*l)=m+k+n2*l
2∗(m+k+n1∗l)=m+k+n2∗l
那么
m
+
k
=
(
n
2
−
2
∗
n
1
)
∗
l
m+k=(n2-2*n1)*l
m+k=(n2−2∗n1)∗l
l
l
l为环路长,
n
1
n1
n1为慢节点整圈数环路,
n
2
n2
n2为快节点整圈数。
现在慢节点在圈中
k
k
k的位置上,再走
m
m
m必能回到环路头,所以快结点从链表头开始走再走到环路头也正好是
m
m
m。