题目:
一个链表中包含环,请找出该链表的环的入口结点。
思路:
先找到环上的一个点,计算出环上的结点个数,然后从定义两个指向链表结点的指针,从链表头开始,快指针先走环的个数个,然后快慢指针一起走,当快指针追上慢指针时,该结点就是环的入口结点。
class Solution {
public:
ListNode* Meeting(ListNode* pHead)
{
if (pHead == NULL)
return NULL;
ListNode* pSlow = pHead->next;
if (pSlow == NULL)
return NULL;
ListNode* pFast = pSlow->next;
//快指针走两步,慢指针走一步
while (pFast&&pSlow)
{
if (pFast == pSlow)
return pFast;
pSlow = pSlow->next;
pFast = pFast->next;
if (pFast != NULL)
pFast = pFast->next;
}
return NULL;
}
//找入口点
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* meet = Meeting(pHead);
if (meet == NULL)
return NULL;
//计算环中结点的个数
int num = 1;
ListNode* pNode1 = meet;
while (pNode1->next != meet)
{
pNode1 = pNode1->next;
++num;
}
//pNode1先走num步
pNode1 = pHead;
for (int i = 0; i < num; ++i)
pNode1 = pNode1->next;
//pNode1和pNode2一起走
ListNode* pNode2 = pHead;
while (pNode1 != pNode2)
{
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pNode1;
}
};
也可以整合在一个函数中。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==NULL || pHead->next==NULL)
return NULL;
ListNode* pFast = pHead;
ListNode* pSlow = pHead;
while(pFast&&pFast->next){
pFast=pFast->next->next;
pSlow=pSlow->next;
if(pFast == pSlow)
break;
}
if(pFast==NULL && pFast->next==NULL)
return NULL;
pFast = pHead;
while(pFast!=pSlow)
{
pFast = pFast->next;
pSlow = pSlow->next;
}
return pFast;
}
};