/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if (!pHead || !pHead->next) return nullptr;
ListNode *slow = pHead->next;
ListNode *fast = pHead->next->next;
while (fast && fast->next && fast != slow) {
fast = fast->next->next;
slow = slow->next;
}
if (!(fast && fast->next)) {
return nullptr;
}
slow = pHead;
while (fast != slow) {
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
思路:先找是否有环。找到后fast在相遇位置,slow回退到pHead,然后两个指针相同速度遍历,相遇时即为环起点。后面的思路可能需要图,感觉手撕的话一般不会要求列等式计算。
设pHead到环起点距离为m,环起点到相遇点为k,环长度为n。相遇前慢节点在环里转了a圈,快节点转了b圈。
因为fast走过的路程是slow的两倍,有2 * (m + a * n + k) = m + b * n + k,化简得m = (b - 2 * a) * n - k。
慢节点从pHead继续出发,到环起始点距离为m;快节点以相同速度走m = (b - 2 * a) * n - k,再加上快节点原本距离环起始点为k,总共离环起始点的距离为(b - 2 * a) * n,即也在环起始点。

京公网安备 11010502036488号