mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
1.6 KiB
1.6 KiB
142. Linked List Cycle II
思路
判断一个链表是否有环并且找到环的开始位置.要求空间复杂度O(1)
和之前普通判断是否有环的思路是类似的, 依然是使用两个指针, 一快一慢, 快指针每次走两步慢指针每次走一步. 若两指针相遇了肯定有环否则遇到NULL则没环. 那么当有环时如何判断环的起始位置呢?
我们假设两指针走了k次后相遇, 链表头到环开始节点距离为S(即所求), 从环开始节点到两指针相遇节点距离为M, 环的长度为R; 则我们有:
- 快指针走的路程2k = S + M + xR, 其中x是快指针走过环的整圈数;
- 慢指针走的路程为k = S + M + yR, 其中y是慢指针走过环的整圈数;
则我们有S + M + xR = 2(S + M + yR), 化简得S + M = (x-y)R. 即我们得到了一个重要的结论: 从表头到相遇节点的距离等于环长的整数倍. 那么我们如果使用两个指针分别从表头和相遇节点开始向后每次走一步, 那么这两个节点走了S步后一定会相遇, 这个相遇节点即所求.
C++
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast = head, *slow=head;
while(fast && fast -> next){
fast = fast -> next -> next;
slow = slow -> next;
if(fast == slow) break;
}
if(fast == NULL || fast -> next == NULL)
return NULL;
fast = head;
while(fast != slow){
fast = fast -> next;
slow = slow -> next;
}
return fast;
}
};