剑指offer 055、 链表中环的入口结点
题目
题解
利用快慢指针,从头结点开始出发,fast指针每次移动两个节点,slow每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
相遇时: slow指针走过的节点数为: x + y
, fast指针走过的节点数:x + y + n (y + z)
因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2: (x + y) * 2 = x + y + n (y + z)
,可得到x = n (y + z) - y
- 当 n为1的时候,公式就化解为
x = z
- 当n大于1时,就是fast指针在环形转n圈之后才遇到 slow指针。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
ListNode* slow = pHead;
ListNode* fast = pHead;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
// 当快慢指针相遇后,一个指针从头结点开始,一个结点从相遇结点开始,直到再次相遇
if (slow == fast) {
ListNode* index1 = pHead;
ListNode* index2 = fast;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return nullptr;
}
};