/* 题目: 如果链表中包含环,如何找出环的入口? */ /* 思路: 双指针: 1、判断是否有环。 fast指针一次2步,slow指针一次1步,当fast与slow相遇时,说明有环。 2、判断环路中节点的个数。 当fast和slow相遇的节点在环上,一个指针固定, 另一个指针循环一周再次遇到该固定指针,遍历的个数即为节点个数。 3、找到入口节点。 fast指针先走k步, 接着,fast和slow指针同时遍历, 相遇节点即为入口节点。 */ #include<iostream> #include<string.h> #include<algorithm> #include<cmath> #include<stdio.h> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; int LoopNodeLength(ListNode* pHead){ int length = 0; ListNode* slow = pHead; ListNode* fast = pHead->next; if(fast == nullptr) return length; while(fast->next != nullptr && fast != slow){ fast = fast->next->next; slow = slow->next; } if(fast->next != nullptr){ fast = slow->next; length = 1; while(fast != slow){ length++; fast = fast->next; } } return length; } ListNode* EntryNodeOfLoop(ListNode* pHead) { if(pHead == nullptr) return nullptr; int length = LoopNodeLength(pHead); if(length == 0) return nullptr; ListNode* fast = pHead; ListNode* slow = pHead; for(int i = 0; i < length; i++){ fast = fast->next; } while(fast != slow){ fast = fast->next; slow = slow->next; } return slow; } int main(){ ListNode* node1 = new ListNode(1); ListNode* node2 = new ListNode(2); ListNode* node3 = new ListNode(3); node1->next = node2; node2->next = node3; node3->next = node1; cout<<EntryNodeOfLoop(node1)->val<<endl; }