题解 | 链表中环的入口结点
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode* fast = pHead; ListNode* slow = pHead; if (fast->next == nullptr) return nullptr; if (fast->next->next == nullptr) return nullptr; fast = fast->next->next; slow = slow->next; while (fast != nullptr) { if (fast == slow) { ListNode* gen1 = pHead; ListNode* gen2 = fast; while (gen1 != gen2) { gen1 = gen1->next; gen2 = gen2->next; } return gen2; } else { // if the size of the linked list is odd number if (fast->next == nullptr) break; fast = fast->next->next; slow = slow->next; } } // if there is nullptr, there is null return nullptr; } };
这个问题主要的问题有两个
- 检查是否有环
- 找到环的入口点
检查环的存在,就需要用到快慢指针(一个速度2,一个速度1)。快指针终归会追上慢指针,如果追上了就是速度只差1,而且通过实践可以知道,即使是最坏的情况,也就是快指针入圈的时候比慢指针多了一格,快指针也能追上。
快慢指针相等,证明环存在。存在之后我们需要找到入口。
数学推导
这里的x=z我们就可以在当前的基础上,设置两个步长为1的指针去移动,相遇的时候就是环的入口#剑指offer#