题目描述
一个链表中包含环,请找出该链表的环的入口结点。
代码
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
//找到一快一慢两个指针相遇的结点,两个指针相遇的结点一定在环中。
ListNode* MeetingNode(ListNode* pHead)
{
if (pHead == NULL) {
return NULL;
}
ListNode *pSlow = pHead ->next;
if (pSlow == NULL) {
return NULL;
}
ListNode *pFast = pHead->next->next;
while (pFast != NULL && pSlow != NULL) {
if (pFast == pSlow) {
return pFast;
}
pSlow = pSlow ->next;
pFast = pFast ->next;
if (pFast != NULL) {
pFast = pFast ->next;
}
}
return NULL;
}
// 在找到环中任意一个结点之后,就能得出环中的结点数目,并找到环中的入口结点。
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode *meetingNode = MeetingNode(pHead);
if (meetingNode == NULL) {
return NULL;
}
// get the number of nodes in loop
int nodesInLoop = 1;
ListNode *pNode1 = meetingNode;
while (pNode1->next != meetingNode) {
pNode1 = pNode1 ->next;
nodesInLoop++;
}
// move pNode1
pNode1 = pHead;
for (int i = 0; i < nodesInLoop; i++) {
pNode1 = pNode1 ->next;
}
// move pNode1 and pNode2
ListNode *pNode2 = pHead;
while (pNode1 != pNode2) {
pNode1 = pNode1 ->next;
pNode2 = pNode2 ->next;
}
return pNode1;
}
};