问题分析:设置两个指针,pSlow初始化为pHead,在后,走的慢;pFast初始化为pHead->next,在前,走的快,二者一定会在环内相遇;二者相遇之后设置计数器,令指针沿着环走一圈,计算环中元素数量;设置两个指针p1和p2,令p1先走环中元素数量的位置,然后两个同时走,二者会在环入口相遇
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { if(pHead==NULL)return NULL; //先计算环中结点的个数 //快慢指针相遇结点一定在环中 //每向前走一步,检验是否为空,避免链表不是环的时候,程序出错 ListNode *pSlow=pHead,*pFast=pHead->next; while(pFast!=NULL&&pSlow!=NULL) { pSlow=pSlow->next; pFast=pFast->next; if(pFast==pSlow) break; if(pFast!=NULL) pFast=pFast->next; } //开始统计环结点数 int countNum=1; ListNode *pTempNode=pFast->next; if(pFast==pSlow&&pFast!=NULL) { while(pTempNode!=pFast) { pTempNode=pTempNode->next; ++countNum; } } else return NULL; //再设两指针,一先一后 ListNode *p1=pHead,*p2=pHead; for(int i=0;i<countNum;i++) p1=p1->next; while(p1!=p2) { p1=p1->next; p2=p2->next; } return p1; } };
这段代码的第一个循环,寻找快慢指针的相遇点,while条件中没有给出循环终止条件pSlow!=pFast,当找到这个点的时候,用break结束循环。这里也可以将这个循环终止条件
ListNode *pSlow=pHead,*pFast=pHead->next; while(pFast!=NULL&&pSlow!=NULL&&pFast!=pSlow) { pSlow=pSlow->next; pFast=pFast->next; if(pFast!=NULL) pFast=pFast->next; }注意:为了防止非正常数据,如输入的指针不是环,最好每走一步,检验指针是否为空