題目描述
給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 null。
爲了表示給定鏈表中的環,我們使用整數 pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環。
說明:不允許修改給定的鏈表。
示例 1:
輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 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 && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
fast = head;
while (fast != slow) {
fast = fast->next;
slow = slow->next;
}
return slow;
}
}
return NULL;
}
};