给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
快慢指针,有环必相遇。设环长c
,环外长d
,自环外起点,从0
开始编号,环内自入口从0开始编号。
二者第一次相遇,快指针走了2n1步,慢指针走了n1步,相遇即(2n1−d)%c=(n1−d)%c,即n1%c=0。
此时将慢指针置回起点,二者同速各走n2=d步,慢指针在入口,快指针在(2n1+n2−d)%c=2n1%c=0处,即二者在入口处相遇。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { if (pHead == nullptr) { return nullptr; } else if (pHead->next == pHead) { return pHead; } else { ListNode *f = pHead, *s = pHead; while (f == pHead || f != s) { s = s->next; f = f->next; if (f == nullptr) { return nullptr; } else { f = f->next; } if (f == nullptr || s == nullptr) { return nullptr; } } s = pHead; while (f != s) { f = f->next; s = s->next; } return f; } } };
|