class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { if(pHead->next==pHead) return pHead; //单个元素成环直接返回头节点 if(pHead->next==NULL) return NULL; //只有一个元素不成环,直接返回null ListNode* fast=pHead->next->next; //定义快指针一次走两个 ListNode* slow=pHead->next; //定义慢指针一次走一个 while(fast!=slow){ //如果表中有环则二者必定在慢指针走完环一圈前相遇 if(fast==NULL) return NULL; //在fast前进的过程中,只要fast=null,则表明表中无环 fast=fast->next; if(fast==NULL) return NULL; fast=fast->next; slow=slow->next; } fast=pHead; //此时快慢指针指向环中的同一个节点,此时令慢指针保存,快指针回到头 while(fast!=slow){ //令快慢指针速度相同往后走,当他们相遇时,就是第一个入环的节点 fast=fast->next; slow=slow->next; } return fast; //此时返回fast或slow都可 } }; /* 原理解释 考虑表中确实有环的情况,快慢指针首次相遇时,慢指针走过的路程时进环前的a和环内的b 而快指针走过的路程是环前的a+环内的b+除b外剩下环的部分c+第二圈走过的b 而此时快指针走过的路程是慢指针的2倍 所以可以得到a+b+b+c=(a+b)*2 所以a=c,即环前的路程和当前相遇位置再走到环入口的路程相同 所以此时令一个指针回到链表头,二者同速前进到相遇,就恰好是环入口,返回即可。 */